Load required packages.

require(phyloseq)
Loading required package: phyloseq
 require(parallelDist)
Loading required package: parallelDist
Warning: package ‘parallelDist’ was built under R version 4.1.2
require(ggplot2)
Loading required package: ggplot2
Warning: package ‘ggplot2’ was built under R version 4.1.2
  require(randomForest)
Loading required package: randomForest
Warning: package ‘randomForest’ was built under R version 4.1.2
randomForest 4.7-1.1
Type rfNews() to see new features/changes/bug fixes.

Attaching package: ‘randomForest’

The following object is masked from ‘package:ggplot2’:

    margin
require(Boruta)
Loading required package: Boruta
Warning: package ‘Boruta’ was built under R version 4.1.2
  require(phyloseq)
require(stats)
  require(dplyr)
Loading required package: dplyr
Warning: package ‘dplyr’ was built under R version 4.1.2

Attaching package: ‘dplyr’

The following object is masked from ‘package:randomForest’:

    combine

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
require(readr)
Loading required package: readr
Warning: package ‘readr’ was built under R version 4.1.2
  require(pheatmap)
Loading required package: pheatmap
require(tidyverse)
Loading required package: tidyverse
Warning: package ‘tidyverse’ was built under R version 4.1.2
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
── Attaching packages ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.2 ──
✔ tibble  3.1.8     ✔ stringr 1.5.0
✔ tidyr   1.2.1     ✔ forcats 0.5.2
✔ purrr   0.3.5     
Warning: package ‘tibble’ was built under R version 4.1.2
Warning: package ‘tidyr’ was built under R version 4.1.2
Warning: package ‘purrr’ was built under R version 4.1.2
Warning: package ‘stringr’ was built under R version 4.1.2
Warning: package ‘forcats’ was built under R version 4.1.2
── Conflicts ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::combine()       masks randomForest::combine()
✖ dplyr::filter()        masks stats::filter()
✖ dplyr::lag()           masks stats::lag()
✖ randomForest::margin() masks ggplot2::margin()
  require(micrUBIfuns)
Loading required package: micrUBIfuns
Loading required package: data.table
Warning: package ‘data.table’ was built under R version 4.1.2
data.table 1.14.6 using 1 threads (see ?getDTthreads).  Latest news: r-datatable.com
**********
This installation of data.table has not detected OpenMP support. It should still work but in single-threaded mode.
This is a Mac. Please read https://mac.r-project.org/openmp/. Please engage with Apple and ask them for support. Check r-datatable.com for updates, and our Mac instructions here: https://github.com/Rdatatable/data.table/wiki/Installation. After several years of many reports of installation problems on Mac, it's time to gingerly point out that there have been no similar problems on Windows or Linux.
**********

Attaching package: ‘data.table’

The following object is masked from ‘package:purrr’:

    transpose

The following objects are masked from ‘package:dplyr’:

    between, first, last

Loading required package: ggsci
Loading required package: ComplexHeatmap
Loading required package: grid
========================================
ComplexHeatmap version 2.8.0
Bioconductor page: http://bioconductor.org/packages/ComplexHeatmap/
Github page: https://github.com/jokergoo/ComplexHeatmap
Documentation: http://jokergoo.github.io/ComplexHeatmap-reference

If you use it in published research, please cite:
Gu, Z. Complex heatmaps reveal patterns and correlations in multidimensional 
  genomic data. Bioinformatics 2016.

The new InteractiveComplexHeatmap package can directly export static 
complex heatmaps into an interactive Shiny app with zero effort. Have a try!

This message can be suppressed by:
  suppressPackageStartupMessages(library(ComplexHeatmap))
========================================
! pheatmap() has been masked by ComplexHeatmap::pheatmap(). Most of the arguments
   in the original pheatmap() are identically supported in the new function. You 
   can still use the original function by explicitly calling pheatmap::pheatmap().


Attaching package: ‘ComplexHeatmap’

The following object is masked from ‘package:pheatmap’:

    pheatmap

Loading required package: vegan
Warning: package ‘vegan’ was built under R version 4.1.2
Loading required package: permute
Warning: package ‘permute’ was built under R version 4.1.2
Loading required package: lattice
This is vegan 2.6-4
require(circlize)
Loading required package: circlize
Warning: package ‘circlize’ was built under R version 4.1.2
========================================
circlize version 0.4.15
CRAN page: https://cran.r-project.org/package=circlize
Github page: https://github.com/jokergoo/circlize
Documentation: https://jokergoo.github.io/circlize_book/book/

If you use it in published research, please cite:
Gu, Z. circlize implements and enhances circular visualization
  in R. Bioinformatics 2014.

This message can be suppressed by:
  suppressPackageStartupMessages(library(circlize))
========================================
  require(phylosmith)
Loading required package: phylosmith
require(phangorn)
Loading required package: phangorn
Warning: package ‘phangorn’ was built under R version 4.1.2
Loading required package: ape
Warning: package ‘ape’ was built under R version 4.1.2

Attaching package: ‘ape’

The following object is masked from ‘package:circlize’:

    degree


Attaching package: ‘phangorn’

The following objects are masked from ‘package:vegan’:

    diversity, treedist
  require(gridExtra)
Loading required package: gridExtra

Attaching package: ‘gridExtra’

The following object is masked from ‘package:dplyr’:

    combine

The following object is masked from ‘package:randomForest’:

    combine
require(pairwiseAdonis)
Loading required package: pairwiseAdonis
Loading required package: cluster
Warning: package ‘cluster’ was built under R version 4.1.2
  require(car)
Loading required package: car
Warning: package ‘car’ was built under R version 4.1.2
Loading required package: carData
Warning: package ‘carData’ was built under R version 4.1.2

Attaching package: ‘car’

The following object is masked from ‘package:purrr’:

    some

The following object is masked from ‘package:dplyr’:

    recode

Load necessary files from Dada2 processing script.

load("/Users/gordoncuster/Desktop/Git_Projects/BeeBread/Data/16S/DADA2outputs/dada2_outputs_16S_BeeBread_wtree.RData")

Read in metadata

metadata<-read.csv("/Users/gordoncuster/Desktop/Git_Projects/BeeBread/Data/BB_sample-metadata.txt", sep = "\t")
rownames(metadata)<-metadata$X
metadata$Region_Site<-paste( metadata$Region, metadata$Site, sep = "")
metadata$Treatment_Site<-paste( metadata$Treatment, metadata$Site, sep = "")

Convert files to correct format for phyloseq object and then rename samples in OTU table to match the format of the metadata file. Create phyloseq object and root phylogenetic tree for usage with distance metrics (e.g., Unifrac).

#assign object type to merge into phyloseq object
md<-sample_data(metadata)
otu<-otu_table(seqtab.nochim, taxa_are_rows = F)
tax_tab<-tax_table(taxa)
#check sample names of both otu table and metadata
#remove .fastq.gz from otu table names
sample_names(otu)<-str_split(sample_names(otu), pattern = ".fastq.gz", simplify = T) [,1]
#since they match, you can create the phyloseq object
bb16S_orig<-phyloseq(md, otu, tax_tab, fitGTR$tree)

#root tree for distance metrics like unifrac
set.seed(11)
phy_tree(bb16S_orig)<-root(phy_tree(bb16S_orig), sample(taxa_names(bb16S_orig), 1), resolve.root = TRUE)
is.rooted(phy_tree(bb16S_orig))
[1] TRUE

#Pre-processing. Rename OTU IDS to something more manageable. We save the ASCV sequences in case we need them later (e.g., BLASTN searches). Create Bacterial and Archaeal phyloseq objects, but first we remove Chloroplasts.

#Extract original IDs for future reference. 
seq_df_w_OTUID<-data.frame(OTUID = 1:ntaxa(bb16S_orig), Sequence = taxa_names(bb16S_orig))
taxa_names(bb16S_orig)<-paste("OTU_" , 1:ntaxa(bb16S_orig), sep = "")


#remove chloroplast
#978 chloroplast or mitochondrial taxa
bb16S_orig_nc<-subset_taxa(bb16S_orig, Family!= "Mitochondria" | is.na(Family) & Order!="Chloroplast" | is.na(Order))


#1337 bacterial taxa - 9 non-bacteria removed. 
bb16S_bac<-subset_taxa(bb16S_orig_nc, Kingdom == "Bacteria")
#9 archaea
bb16S_arch<-subset_taxa(bb16S_orig_nc, Kingdom == "Archaea")

Remove control samples as there is only as single replicate of each.

ps_wo_control<-subset_samples(bb16S_bac, Treatment != "none")

Examine rarefaction curves. Plateau in most samples under the 1.5k read mark.

rarecurve(otu_table(ps_wo_control), step=50, cex=0.5, main = "Rarefaction Curve", ylab="Richness", xlab="Read Depth")
Error in as(x, "matrix")[i, j, drop = FALSE] : 
  (subscript) logical subscript too long
set.seed(11)
sort(sample_sums(ps_wo_control))
  Dal_IPM1054_A   Dal_CON1058_A   Dal_CON1057_A   Spr_CON3017_A   Dal_IPM1055_A    Dal_CF1052_A    Spr_CF3016_A   Dal_IPM1055_B   Dal_CON1058_B   Sum_IPM4002_B 
            409             496             894            1188            1378            1469            1718            1962            2036            2037 
  Spr_CON3017_B    Sla_CF2066_B   Sla_IPM2071_B    Dal_CF1051_A    Dal_CF1051_B   Dal_IPM1054_B   Dal_CON1057_B    Sla_CF2065_B   Spr_CON3019_A   Sla_IPM2070_A 
           2254            2287            2288            2318            2359            2370            2396            2744            2835            2864 
Spr_CON3019_Be2    Spr_CF3013_A   Spr_IPM3023_B   Sla_CON2061_A   Spr_IPM3023_A   Sum_CON4011_B   Bel_IPM3042_A   Sla_IPM2070_B    Dal_CF1052_B   Sum_IPM4001_A 
           2886            3503            3513            3871            3898            4039            4196            4553            4710            4721 
   Sla_CF2066_A    Bel_CF3047_A   Sum_CON4011_A   Sum_IPM4001_B    Spr_CF3016_B    Sum_CF4006_B    Sum_CF4005_A    Bel_CF3045_B    Sla_CF2065_A   Sum_IPM4002_A 
           4749            4845            5502            5625            5693            5819            5935            5938            6648            6815 
  Spr_IPM3024_A    Ber_CF2006_B   Bel_CON3039_A   Sum_CON4010_B   Sla_CON2063_A   Ber_IPM2002_B   Spr_IPM3024_B    Spr_CF3013_B   Bel_CON3037_A    Sum_CF4006_A 
           6930            7047            7119            7147            7253            7462            7669            7888            8129            8276 
  Bel_IPM3042_B Ber_CON2011_Be2    Sum_CF4005_B    Bel_CF3045_A   Sum_CON4010_A   Ber_CON2010_B   Ber_CON2011_A   Bel_IPM3044_B   Sla_IPM2071_A   Bel_CON3039_B 
           9187            9315            9820           10444           10531           11063           11158           11247           12197           12295 
  Sla_CON2061_B    Bel_CF3047_B    Ber_CF2007_A   Bel_IPM3044_A    Ber_CF2007_B   Ber_IPM2002_A   Ber_CON2010_A   Bel_CON3037_B   Ber_IPM2001_A   Ber_IPM2001_B 
          13463           14099           15170           15601           17086           18639           19194           20875           21680           22834 
   Ber_CF2006_A   Sla_CON2063_B 
          33732           47127 
summary(sample_sums(ps_wo_control))
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    409    2812    5877    8020   10466   47127 
sd(sample_sums(ps_wo_control))
[1] 7801.64
bb16S_bac_rarefy<-rarefy_even_depth(ps_wo_control, sample.size = 1100, rngseed = 14, trimOTUs = T)
`set.seed(14)` was used to initialize repeatable random subsampling.
Please record this for your records so others can reproduce.
Try `set.seed(14); .Random.seed` for the full vector
...
3 samples removedbecause they contained fewer reads than `sample.size`.
Up to first five removed samples are: 

Dal_CON1057_ADal_CON1058_ADal_IPM1054_A
...
486OTUs were removed because they are no longer 
present in any sample after random subsampling

...
#517 otus were removed during rarefaction. 

#To move forward, we can hellinger transform and go from there.
bb16S_bac_hellinger<-transform_sample_counts(ps_wo_control, function(x) sqrt(x / sum(x)))

#maximum liklihood point estimates
bb16S_bac_ML<- transform_sample_counts(ps_wo_control, function(x) x / sum(x))

#Alpha Diversity

sf2a <- plot_richness(bb16S_bac_rarefy, x = "Site", measures = c("Shannon", "Observed", "Chao1"), color = "Site") + geom_boxplot() + ggtitle("Sampling Location") + theme_classic()  + xlab("Sampling Location")  + theme(axis.text=element_text(size=12, angle = 45, hjust = 0.75),
        axis.title=element_text(size=14))

sf2b <- plot_richness(bb16S_bac_rarefy, x = "Site", measures = c("Shannon", "Observed", "Chao1"), color = "Treatment") + geom_boxplot() + ggtitle("Sampling Location by Treatment") + theme_classic() + ylab("") + xlab("Sampling Location") +theme(axis.text=element_text(size=12, angle = 45, hjust = 0.75),
        axis.title=element_text(size=14))

sf2c <-plot_richness(bb16S_bac_rarefy, x = "Site", measures = c("Shannon", "Observed", "Chao1"), color = "Timepoint") + geom_boxplot() + ggtitle("Sampling Location by Sammpling Time") + theme_classic() + xlab("Sampling Location")  +theme(axis.text=element_text(size=12, angle = 45, hjust = 0.75),
        axis.title=element_text(size=14))

sf2d <-plot_richness(bb16S_bac_rarefy, x = "Timepoint", measures = c("Shannon", "Observed", "Chao1"), color = "Treatment") + geom_boxplot() + ggtitle("Treatment by Sampling Time") + theme_classic() + ylab("") + xlab("Sampling Timepoint")  +theme(axis.text=element_text(size=12, angle = 45, hjust =0.75),
        axis.title=element_text(size=14))

sf2 <- grid.arrange(sf2a, sf2b, sf2c, sf2d)

plot(sf2)

Calculate alpha diversity metrics

#create alpha diversity table and prep data to include grouping columns
richness_BB16S_bac<-estimate_richness(bb16S_bac_rarefy, measures = c("Shannon", "Observed", "Chao1"))
#add metadata
richness_BB16S_bac$Site<-sample_data(bb16S_bac_rarefy)$Site
richness_BB16S_bac$Timepoint<-sample_data(bb16S_bac_rarefy)$Timepoint
richness_BB16S_bac$Treatment<-sample_data(bb16S_bac_rarefy)$Treatment
richness_BB16S_bac$Treatment_Timepoint<-sample_data(bb16S_bac_rarefy)$Treatment_Timepoint

Tests of Shannon diversity

#ANOVA and Tukey's PW comparisons
#Run a full 3 way ANOVA with interactions
mod<-aov(Shannon ~ Site * Treatment * Timepoint, data = richness_BB16S_bac)
#residuals look fine. 
shapiro.test(mod$residuals)
hist(mod$residuals)
summary(mod)
#Summary of model shows site and timepoint significant predictors
#Interaction of site and timepoint

#test of heterogentity 
leveneTest(Shannon ~ Site, data = richness_BB16S_bac)
leveneTest(Shannon ~ Treatment, data = richness_BB16S_bac)
leveneTest(Shannon ~ Timepoint, data = richness_BB16S_bac)

#significant Levene's test for Site. We will run an additional Kruskal Wallis for site. 
kruskal.test(Shannon ~ Site, data = richness_BB16S_bac)

#What about pairwise differences in site
TukeyHSD(mod, "Site")
plot(TukeyHSD(mod, "Site"), las=1, cex.axis = 0.4)

#Several significant pairwise differences to accompany the significant global test for interaction term. We can
TukeyHSD(mod, "Site:Timepoint")
plot(TukeyHSD(mod, "Site:Timepoint"), las=1, cex.axis = 0.4)

Tests of Chao 1

#ANOVA and Tukey's PW comparisons
#Run a full 3 way ANOVA with interactions
mod<-aov(Chao1 ~ Site * Treatment * Timepoint, data = richness_BB16S_bac)
#residuals look fine. 
shapiro.test(mod$residuals)
hist(mod$residuals)
summary(mod)

leveneTest(Chao1 ~ Site, data = richness_BB16S_bac)
leveneTest(Chao1 ~ Treatment, data = richness_BB16S_bac)
leveneTest(Chao1 ~ Timepoint, data = richness_BB16S_bac)

#Site and the interactions with site are significant. 

TukeyHSD(mod, "Site")
plot(TukeyHSD(mod, "Site"), las=1, cex.axis = 0.4)

Tests of Observed - unique taxa in a sample.

#ANOVA and Tukey's PW comparisons
#Run a full 3 way ANOVA with interactions
mod<-aov(Observed ~ Site * Treatment * Timepoint, data = richness_BB16S_bac)
#residuals look fine. 
shapiro.test(mod$residuals)
summary(mod)
hist(mod$residuals)

leveneTest(Observed ~ Site, data = richness_BB16S_bac)
leveneTest(Observed ~ Treatment, data = richness_BB16S_bac)
leveneTest(Observed ~ Timepoint, data = richness_BB16S_bac)

#Summary of model shows site and timepoint to be a significant predictor as well as the site interaction terms.
TukeyHSD(mod, "Site")
plot(TukeyHSD(mod, "Site"), las=1, cex.axis = 0.4)

#Beta diversity Full model with no strata argument

#extract data from phyloseq object
tab_adonis<-data.frame(otu_table(bb16S_bac_ML))
sd_adonis<-data.frame(sample_data(bb16S_bac_ML))
sd_adonis$Treatment <-as.factor(sd_adonis$Treatment)
sd_adonis$Site <-as.factor(sd_adonis$Site)
dist_w<-phyloseq::distance(bb16S_bac_ML, method =  "wunifrac")
dist_uw<-phyloseq::distance(bb16S_bac_ML, method =  "unifrac")

#full model with no strata arguemnt. Essentially the effect of each main effect without controlling for any potential groups. 

#weighted
adonis2(dist_w ~  Site * Treatment * Timepoint, data= sd_adonis, permutations = 10000)
#unweighted
adonis2(dist_uw ~  Site * Treatment * Timepoint, data= sd_adonis, permutations = 10000)

#with strata argument
adonis2(dist_w ~  Site * Treatment * Timepoint, data= sd_adonis, strata = sd_adonis$Site, permutations = 10000)
adonis2(dist_uw ~  Site * Treatment * Timepoint, data= sd_adonis, strata = sd_adonis$Site, permutations = 10000)


##PW adonis w/ strata = site
pairwise.adonis2(dist_uw ~ Treatment + Timepoint, strata = "Site",  data= sd_adonis, nperm = 10000)

Ordinations

#weighted Unifrac
ord_nmds<-ordinate(physeq = bb16S_bac_ML, method = "NMDS", distance = "wunifrac")
ord_nmds$stress
plot_ordination(physeq = bb16S_bac_ML, ordination = ord_nmds, type = "Samples", color = "Site", shape = "Treatment" ) + theme_classic() + ggtitle("Weighted Unifrac NMDS") + theme(plot.title = element_text(hjust = 0.5, size = 18)) + geom_point(size = 3) + theme(axis.text = element_text(size = 14), axis.title=element_text(size=14))
#ggsave("../../Writing/Final_Figs/Weighted_Unifrac_NMDS.eps")
#strongest grouping by Site. Time point also has a smaller effect, but these groupings are more clear than in the CAP ordination. There are several outlier samples that ordinate far to the right on the NMDS1 axis. 

#unweighted Unifrac
ord_nmds<-ordinate(physeq = bb16S_bac_ML, method = "NMDS", distance = "unifrac")
ord_nmds$stress
plot_ordination(physeq = bb16S_bac_ML, ordination = ord_nmds, type = "Samples", color = "Site", shape = "Treatment" ) + theme_classic() + ggtitle("Unweighted Unifrac NMDS") + theme(plot.title = element_text(hjust = 0.5, size = 18)) + geom_point(size = 3) + theme(axis.text = element_text(size = 14), axis.title=element_text(size=14))
#ggsave("../../Writing/Final_Figs/Unweighted_Unifrac_NMDS.eps")

Sampling time 2 (post treatment)

#post-treatment samples
bb16S_bac_ML_B<-subset_samples(bb16S_bac_ML, Timepoint == "B")

#extract data from phyloseq object for post-treatment
sd_adonis<-data.frame(sample_data(bb16S_bac_ML_B))
sd_adonis$Treatment <-as.factor(sd_adonis$Treatment)
sd_adonis$Site <-as.factor(sd_adonis$Site)
dist_wb<-phyloseq::distance(bb16S_bac_ML_B, method =  "wunifrac")
dist_uwb<-phyloseq::distance(bb16S_bac_ML_B, method =  "unifrac")


#with strata argument
adonis2(dist_wb ~  Site * Treatment, data= sd_adonis, strata = sd_adonis$Site, permutations = 10000)
adonis2(dist_uwb ~  Site * Treatment, data= sd_adonis, strata = sd_adonis$Site, permutations = 10000)

pairwise.adonis2(dist_uwb ~Treatment, strata = "Site", data = sd_adonis, nperm = 10000)

#ordinations
#weighted Unifrac
ord_nmds<-ordinate(physeq = bb16S_bac_ML_B, method = "NMDS", distance = "wunifrac")
ord_nmds$stress
plot_ordination(physeq = bb16S_bac_ML_B, ordination = ord_nmds, type = "Samples", color = "Site", shape = "Treatment" ) + theme_classic() + ggtitle("Weighted Unifrac NMDS") + theme(plot.title = element_text(hjust = 0.5, size = 18)) + geom_point(size = 3)
ggsave("../../Writing/Final_Figs/Time2_Weighted_Unifrac_NMDS.pdf")
#strongest grouping by Site. Time point also has a smaller effect, but these groupings are more clear than in the CAP ordination. There are several outlier samples that ordinate far to the right on the NMDS1 axis. 

#unweighted Unifrac
ord_nmds<-ordinate(physeq = bb16S_bac_ML_B, method = "NMDS", distance = "unifrac")
ord_nmds$stress
plot_ordination(physeq = bb16S_bac_ML_B, ordination = ord_nmds, type = "Samples", color = "Site", shape = "Treatment" ) + theme_classic() + ggtitle("Unweighted Unifrac NMDS") + theme(plot.title = element_text(hjust = 0.5, size = 18)) + geom_point(size = 3)
ggsave("../../Writing/Final_Figs/Time2_Unweighted_Unifrac_NMDS.pdf")

create taxa bar plot to display makeup

sort(table(data.frame(tax_table(bb16S_bac_rarefy))$Phylum), decreasing = TRUE)
length(unique(data.frame(tax_table(bb16S_bac_rarefy))$Phylum))

sort(table(data.frame(tax_table(bb16S_bac_rarefy))$Order), decreasing = TRUE)
length(unique(data.frame(tax_table(bb16S_bac_rarefy))$Order))

sort(table(data.frame(tax_table(bb16S_bac_rarefy))$Family), decreasing = TRUE)
length(unique(data.frame(tax_table(bb16S_bac_rarefy))$Family))

plot_bar(subset_samples(bb16S_bac_rarefy, Timepoint == "A"), fill = "Phylum")  + scale_fill_manual(values = col_vector) + geom_bar(stat = "identity")+ coord_flip()
ggsave("../../Writing/Final_Figs/taxabarA.pdf")

plot_bar(subset_samples(bb16S_bac_rarefy, Timepoint == "B"), fill = "Phylum")  + scale_fill_manual(values = col_vector) + geom_bar(stat = "identity")+ coord_flip()
ggsave("../../Writing/Final_Figs/taxabarB.pdf")

#Core analysis

#create super long color vector
col_vector <- c("#000000", "#FFFF00", "#1CE6FF", "#FF34FF", "#FF4A46", "#008941", "#006FA6", "#A30059",
        "#FFDBE5", "#7A4900", "#0000A6", "#63FFAC", "#B79762", "#004D43", "#8FB0FF", "#997D87",
        "#5A0007", "#809693", "#FEFFE6", "#1B4400", "#4FC601", "#3B5DFF", "#4A3B53", "#FF2F80",
        "#61615A", "#BA0900", "#6B7900", "#00C2A0", "#FFAA92", "#FF90C9", "#B903AA", "#D16100",
        "#DDEFFF", "#000035", "#7B4F4B", "#A1C299", "#300018", "#0AA6D8", "#013349", "#00846F",
        "#372101", "#FFB500", "#C2FFED", "#A079BF", "#CC0744", "#C0B9B2", "#C2FF99", "#001E09",
        "#00489C", "#6F0062", "#0CBD66", "#EEC3FF", "#456D75", "#B77B68", "#7A87A1", "#788D66",
        "#885578", "#FAD09F", "#FF8A9A", "#D157A0", "#BEC459", "#456648", "#0086ED", "#886F4C",
        
        "#34362D", "#B4A8BD", "#00A6AA", "#452C2C", "#636375", "#A3C8C9", "#FF913F", "#938A81",
        "#575329", "#00FECF", "#B05B6F", "#8CD0FF", "#3B9700", "#04F757", "#C8A1A1", "#1E6E00",
        "#7900D7", "#A77500", "#6367A9", "#A05837", "#6B002C", "#772600", "#D790FF", "#9B9700",
        "#549E79", "#FFF69F", "#201625", "#72418F", "#BC23FF", "#99ADC0", "#3A2465", "#922329",
        "#5B4534", "#FDE8DC", "#404E55", "#0089A3", "#CB7E98", "#A4E804", "#324E72", "#6A3A4C",
        "#83AB58", "#001C1E", "#D1F7CE", "#004B28", "#C8D0F6", "#A3A489", "#806C66", "#222800",
        "#BF5650", "#E83000", "#66796D", "#DA007C", "#FF1A59", "#8ADBB4", "#1E0200", "#5B4E51",
        "#C895C5", "#320033", "#FF6832", "#66E1D3", "#CFCDAC", "#D0AC94", "#7ED379", "#012C58",
        
        "#7A7BFF", "#D68E01", "#353339", "#78AFA1", "#FEB2C6", "#75797C", "#837393", "#943A4D",
        "#B5F4FF", "#D2DCD5", "#9556BD", "#6A714A", "#001325", "#02525F", "#0AA3F7", "#E98176",
        "#DBD5DD", "#5EBCD1", "#3D4F44", "#7E6405", "#02684E", "#962B75", "#8D8546", "#9695C5",
        "#E773CE", "#D86A78", "#3E89BE", "#CA834E", "#518A87", "#5B113C", "#55813B", "#E704C4",
        "#00005F", "#A97399", "#4B8160", "#59738A", "#FF5DA7", "#F7C9BF", "#643127", "#513A01",
        "#6B94AA", "#51A058", "#A45B02", "#1D1702", "#E20027", "#E7AB63", "#4C6001", "#9C6966",
        "#64547B", "#97979E", "#006A66", "#391406", "#F4D749", "#0045D2", "#006C31", "#DDB6D0",
        "#7C6571", "#9FB2A4", "#00D891", "#15A08A", "#BC65E9", "#FFFFFE", "#C6DC99", "#203B3C",
        "#671190", "#6B3A64", "#F5E1FF", "#FFA0F2", "#CCAA35", "#374527", "#8BB400", "#797868",
        "#C6005A", "#3B000A", "#C86240", "#29607C", "#402334", "#7D5A44", "#CCB87C", "#B88183",
        "#AA5199", "#B5D6C3", "#A38469", "#9F94F0", "#A74571", "#B894A6", "#71BB8C", "#00B433",
        "#789EC9", "#6D80BA", "#953F00", "#5EFF03", "#E4FFFC", "#1BE177", "#BCB1E5", "#76912F",
        "#003109", "#0060CD", "#D20096", "#895563", "#29201D", "#5B3213", "#A76F42", "#89412E",
        "#1A3A2A", "#494B5A", "#A88C85", "#F4ABAA", "#A3F3AB", "#00C6C8", "#EA8B66", "#958A9F",
        "#BDC9D2", "#9FA064", "#BE4700", "#658188", "#83A485", "#453C23", "#47675D", "#3A3F00",
        "#061203", "#DFFB71", "#868E7E", "#98D058", "#6C8F7D", "#D7BFC2", "#3C3E6E", "#D83D66",
        "#2F5D9B", "#6C5E46", "#D25B88", "#5B656C", "#00B57F", "#545C46", "#866097", "#365D25",
        "#252F99", "#00CCFF", "#674E60", "#FC009C", "#92896B")

calculate core at genus and asv level using rarefied data

Core Genus

#core asv adonis
tab_adonis<-data.frame(otu_table(core_genus))
sd_adonis<-data.frame(sample_data(core_genus))
sd_adonis$Treatment <-as.factor(sd_adonis$Treatment)
sd_adonis$Site <-as.factor(sd_adonis$Site)
dist_core_w_genus<-phyloseq::distance(core_genus, method =  "wunifrac")
dist_core_uw_genus<-phyloseq::distance(core_genus, method =  "unifrac")

#weighted unifrac
adonis2(dist_core_w_genus ~  Site * Treatment * Timepoint, data= sd_adonis, strata = sd_adonis$Site, permutations = 1000)
#unweighted unifrac
adonis2(dist_core_uw_genus ~  Site * Treatment * Timepoint, data= sd_adonis, strata = sd_adonis$Site, permutations = 1000)

#ordinations
#weighted Unifrac
ord_nmds<-ordinate(physeq = core_genus, method = "NMDS", distance = "wunifrac")
ord_nmds$stress
plot_ordination(physeq = core_genus, ordination = ord_nmds, type = "Samples", color = "Site", shape = "Treatment" ) + theme_classic() + ggtitle("Core Genera Weighted Unifrac NMDS") + theme(plot.title = element_text(hjust = 0.5, size = 18)) + geom_point(size = 3)  + theme(axis.text = element_text(size = 14), axis.title=element_text(size=14))
ggsave("../../Writing/Final_Figs/CoreGenus_Weighted_Unifrac_NMDS.eps")
#strongest grouping by Site. Time point also has a smaller effect, but these groupings are more clear than in the CAP ordination. There are several outlier samples that ordinate far to the right on the NMDS1 axis. 

#unweighted Unifrac
ord_nmds<-ordinate(physeq = core_genus, method = "NMDS", distance = "unifrac")
ord_nmds$stress
plot_ordination(physeq = core_genus, ordination = ord_nmds, type = "Samples", color = "Site", shape = "Treatment" ) + theme_classic() + ggtitle("Core Genera Unweighted Unifrac NMDS") + theme(plot.title = element_text(hjust = 0.5, size = 18)) + geom_point(size = 3) + theme(axis.text = element_text(size = 14), axis.title=element_text(size=14))
ggsave("../../Writing/Final_Figs/CoreGenus_Unweighted_Unifrac_NMDS.eps")

Visualization of core microbiome using barplot

#pull out core genera names
core_genus_names<-rownames(tax_table(core_genus))
genus_OTU_table<-data.frame(t(otu_table(bb16S_bac_rarefy_tax_genus)))
#check orientation of otu table
rownames(genus_OTU_table)
#add columns corresponding to core status, % sites, % reads
genus_OTU_table$Core <- NA 
for(i in 1:nrow(genus_OTU_table)){
  if(rownames(genus_OTU_table)[i] %in% core_genus_names == T){
  genus_OTU_table[i,]$Core <- "Core"
  } else{
  genus_OTU_table[i,]$Core <- "NonCore"
  }
}

#Prevalence column
genus_OTU_table$prev <- NA
for(i in 1:nrow(genus_OTU_table)){
  genus_OTU_table[i,]$prev<-table(genus_OTU_table[i,(1:69)] > 0)["TRUE"]/ 69}

#proportional abundance
genus_OTU_table$abund <- NA
  for(i in 1:nrow(genus_OTU_table)){
  genus_OTU_table[i,]$abund <- rowSums(genus_OTU_table[i,c(1:69)])/sum(colSums(genus_OTU_table[,c(1:69)]))
  }

dat<-genus_OTU_table[,c(70:72)]
dat$otu <- as.factor(rownames(dat))
dat$otu <- reorder(dat$otu, -dat$prev )
dat$Phylum <- as.factor(data.frame(tax_table(bb16S_bac_rarefy_tax_genus))$Phylum)
dat$number <- 1:nrow(dat)

ggplot(dat, aes(x = otu, y=prev, fill = Phylum)) +
  geom_bar(stat="identity") + scale_fill_manual(values=col_vector) + theme_classic() +
  theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank()) + ylab("Prevalance") + theme(legend.position = "none")
#ggsave("../../Writing/Final_Figs/core_prev_owlegend.eps")

ggplot(dat, aes(x = otu, y=abund,  fill = Phylum)) +
  geom_bar(stat="identity") + scale_fill_manual(values=col_vector) + theme_classic()  + scale_y_reverse() + theme(axis.text.x = element_text(size = 4 , angle = 45, hjust = 1))
#ggsave("../../Writing/Final_Figs/core_abund.eps")

ggplot(dat, aes(x = otu, y=abund,  fill = Phylum)) +
  geom_bar(stat="identity") + scale_fill_manual(values=col_vector) + theme_classic()  + scale_y_reverse() + theme(axis.text.x = element_text(size = 4 , angle = 45, hjust = 1)) + theme(legend.position = "none") + ylab("Proportional Abundance") + xlab("OTU ID")
#ggsave("../../Writing/Final_Figs/core_abund_wolegend.eps")


#color by core inclusion

ggplot(dat, aes(x = otu, y=prev, fill = Core)) +
  geom_bar(stat="identity") + scale_fill_manual(values=c("#88CCEE", "#999933")) + 
  theme_classic() +
  theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank()) + ylab("Prevalance") + theme(legend.position = "none")  + theme(axis.text.y = element_text(size=12), axis.title.y = element_text(size = 16))
ggsave("../../Writing/Final_Figs/core_prev_owlegend_Core.eps")

ggplot(dat, aes(x = otu, y=abund,  fill = Core)) +
  geom_bar(stat="identity") + scale_fill_manual(values=c("#88CCEE", "#999933")) + 
  theme_classic()  + scale_y_reverse() + theme(axis.text.x = element_text(size = 4 , angle = 45, hjust = 1, face = "bold"))+ theme( axis.text.x=element_blank(), axis.ticks.x=element_blank())  + theme(axis.text.y = element_text(size=12), axis.title.y = element_text(size = 16))
ggsave("../../Writing/Final_Figs/core_abund_Core.eps")

ggplot(dat, aes(x = otu, y=abund,  fill = Core)) +
  geom_bar(stat="identity") +  scale_fill_manual(values=c("#88CCEE", "#999933")) +
  theme_classic()  + scale_y_reverse() +# theme(axis.text.x = element_text(size = 4 , angle = 45, hjust = 1)) + 
theme(legend.position = "none") + ylab("Proportional Abundance") + xlab("OTU") + theme(axis.text.x=element_blank(), axis.ticks.x=element_blank()) + theme(axis.text.y = element_text(size=12), axis.title.y = element_text(size = 16))
ggsave("../../Writing/Final_Figs/core_abund_wolegend_Core.eps")

Acidophilic bacteria

analysis of lactic acid bacteria and acetic acid bacteria at time pont 2 (following application)

bb16S_bac_ML_B<-subset_samples(bb16S_bac_ML, Timepoint == "B")
#ACETO
#36 taxa
acetobacter <- subset_taxa(bb16S_bac_ML_B, Family =="Acetobacteraceae")
acetobacter_glomed<- tax_glom(acetobacter, taxrank = "Family")
Warning in FUN(X[[i]], ...) :
  merge_taxa attempted to reduce tree to 1 or fewer tips.
 tree replaced with NULL.
#anova for all taxa combined
dat<-data.frame(otu_table(acetobacter_glomed))
samp_d<-data.frame(sample_data(acetobacter_glomed))
merged_dat<-cbind(dat, samp_d)
#check to make sure md and otu table are in same order. All should be true. 
table(merged_dat$X == rownames(merged_dat))

TRUE 
  36 
##mod<-aov(OTU_40 ~ Treatment, data = merged_dat)
#summary(mod)
#plot(residuals(mod))
#boxplot(merged_dat$OTU_40 ~ merged_dat$Treatment)

#baruta for individual taxa
aceto_df <- cbind(data.frame(otu_table(acetobacter)), data.frame(sample_data(acetobacter)))
table(aceto_df$X == rownames(aceto_df))

TRUE 
  36 
boxplot(aceto_df$OTU_82 ~ aceto_df$Treatment)

View(tax_table(acetobacter))
#otu 82 ID'ed by baruta. More abundant in ORG. Taxonomy for this taxa "Acetobacteraceae, Bombella"

for(i in 1:length(names(data.frame(otu_table(acetobacter))))){
  boxplot(unlist(aceto_df[i]) ~ aceto_df$Treatment)
}


#very zero inflated so we will not use anova. 
#for(i in 1:length(names(data.frame(otu_table(acetobacter))))){
#  mod<-aov(unlist(aceto_df[i]) ~ aceto_df$Treatment)
#  summary(mod)
#  print(summary(mod))
#  print(names(aceto_df[i]))
#}

for(i in 1:length(names(data.frame(otu_table(acetobacter))))){
  mod<-kruskal.test(unlist(aceto_df[i]) ~ aceto_df$Treatment)
  print(mod)
  print(names(aceto_df[i]))
}

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 0.79956, df = 2, p-value = 0.6705

[1] "OTU_40"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 1.1129, df = 2, p-value = 0.5732

[1] "OTU_77"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 6.2678, df = 2, p-value = 0.04355

[1] "OTU_82"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 3.9036, df = 2, p-value = 0.142

[1] "OTU_101"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 2.3717, df = 2, p-value = 0.3055

[1] "OTU_122"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 3.7257, df = 2, p-value = 0.1552

[1] "OTU_152"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 0.056997, df = 2, p-value = 0.9719

[1] "OTU_181"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 0.75967, df = 2, p-value = 0.684

[1] "OTU_282"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 1.031, df = 2, p-value = 0.5972

[1] "OTU_694"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = NaN, df = 2, p-value = NA

[1] "OTU_714"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 2, df = 2, p-value = 0.3679

[1] "OTU_1129"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 2, df = 2, p-value = 0.3679

[1] "OTU_1246"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 2, df = 2, p-value = 0.3679

[1] "OTU_1289"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 2, df = 2, p-value = 0.3679

[1] "OTU_1322"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = NaN, df = 2, p-value = NA

[1] "OTU_1346"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = NaN, df = 2, p-value = NA

[1] "OTU_1374"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 2, df = 2, p-value = 0.3679

[1] "OTU_1446"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 2, df = 2, p-value = 0.3679

[1] "OTU_1522"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = NaN, df = 2, p-value = NA

[1] "OTU_1608"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 2, df = 2, p-value = 0.3679

[1] "OTU_1628"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = NaN, df = 2, p-value = NA

[1] "OTU_1647"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = NaN, df = 2, p-value = NA

[1] "OTU_1657"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 2, df = 2, p-value = 0.3679

[1] "OTU_1702"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 2, df = 2, p-value = 0.3679

[1] "OTU_1709"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 2, df = 2, p-value = 0.3679

[1] "OTU_1755"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 2, df = 2, p-value = 0.3679

[1] "OTU_1756"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 2, df = 2, p-value = 0.3679

[1] "OTU_1809"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = NaN, df = 2, p-value = NA

[1] "OTU_1816"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 2, df = 2, p-value = 0.3679

[1] "OTU_1919"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = NaN, df = 2, p-value = NA

[1] "OTU_1928"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = NaN, df = 2, p-value = NA

[1] "OTU_2017"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 2, df = 2, p-value = 0.3679

[1] "OTU_2037"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 2, df = 2, p-value = 0.3679

[1] "OTU_2215"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 2, df = 2, p-value = 0.3679

[1] "OTU_2255"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = NaN, df = 2, p-value = NA

[1] "OTU_2286"

    Kruskal-Wallis rank sum test

data:  unlist(aceto_df[i]) by aceto_df$Treatment
Kruskal-Wallis chi-squared = 2, df = 2, p-value = 0.3679

[1] "OTU_2306"
#OTU 82 ID'ed as significantly different among groups
pairwise.wilcox.test(aceto_df$OTU_82, aceto_df$Treatment)
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties
Warning in wilcox.test.default(xi, xj, paired = paired, ...) :
  cannot compute exact p-value with ties

    Pairwise comparisons using Wilcoxon rank sum test with continuity correction 

data:  aceto_df$OTU_82 and aceto_df$Treatment 

    CF    CON  
CON 0.190 -    
ORG 0.058 0.241

P value adjustment method: holm 
boxplot(aceto_df$OTU_82~ aceto_df$Treatment)

ggplot(aceto_df, aes(x = Treatment, y = OTU_82, color = Treatment)) + geom_boxplot()  + theme_classic()  + theme(axis.text = element_text(size = 14), axis.title=element_text(size=14))
ggsave("/Users/gordoncuster/Desktop/Git_Projects/BeeBread/Writing/Final_Figs/OTU_82_ML.eps")
Saving 7.29 x 4.51 in image

#no significant differences across treatment types
##LACTO

#75 taxa
lactobac <- subset_taxa(bb16S_bac_ML_B, Order =="Lactobacillales")
lactobac_glomed <- tax_glom(lactobac, taxrank = "Order")

dat<-data.frame(otu_table(lactobac_glomed))
samp_d<-data.frame(sample_data(lactobac_glomed))
merged_dat<-cbind(dat, samp_d)
#check to make sure md and otu table are in same order. All should be true. 
table(merged_dat$X == rownames(merged_dat))

lacto_df <- cbind(data.frame(otu_table(lactobac)), data.frame(sample_data(lactobac)))
table(lacto_df$X == rownames(lacto_df))
boxplot(lacto_df$OTU_530 ~ lacto_df$Treatment)
View(tax_table(lactobac))



for(i in 1:length(names(data.frame(otu_table(lactobac))))){
  boxplot(unlist(lacto_df[i]) ~ lacto_df$Treatment)
}

for(i in 1:length(names(data.frame(otu_table(lactobac))))){
   mod<-kruskal.test(unlist(lacto_df[i]) ~ lacto_df$Treatment)
  print(mod)
  print(names(lacto_df[i]))
}

https://stackoverflow.com/questions/61796484/stacked-bar-chart-with-count-above-and-below-x-axis

LS0tCnRpdGxlOiAiQkIgMTZTIE1CIEZpbmFsIEFuYWx5c2VzIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCkxvYWQgcmVxdWlyZWQgcGFja2FnZXMuCgpgYGB7cn0KcmVxdWlyZShwaHlsb3NlcSkKIHJlcXVpcmUocGFyYWxsZWxEaXN0KQpyZXF1aXJlKGdncGxvdDIpCiAgcmVxdWlyZShyYW5kb21Gb3Jlc3QpCnJlcXVpcmUoQm9ydXRhKQogIHJlcXVpcmUocGh5bG9zZXEpCnJlcXVpcmUoc3RhdHMpCiAgcmVxdWlyZShkcGx5cikKcmVxdWlyZShyZWFkcikKICByZXF1aXJlKHBoZWF0bWFwKQpyZXF1aXJlKHRpZHl2ZXJzZSkKICByZXF1aXJlKG1pY3JVQklmdW5zKQpyZXF1aXJlKGNpcmNsaXplKQogIHJlcXVpcmUocGh5bG9zbWl0aCkKcmVxdWlyZShwaGFuZ29ybikKICByZXF1aXJlKGdyaWRFeHRyYSkKcmVxdWlyZShwYWlyd2lzZUFkb25pcykKICByZXF1aXJlKGNhcikKYGBgCgpMb2FkIG5lY2Vzc2FyeSBmaWxlcyBmcm9tIERhZGEyIHByb2Nlc3Npbmcgc2NyaXB0LgoKYGBge3J9CmxvYWQoIi9Vc2Vycy9nb3Jkb25jdXN0ZXIvRGVza3RvcC9HaXRfUHJvamVjdHMvQmVlQnJlYWQvRGF0YS8xNlMvREFEQTJvdXRwdXRzL2RhZGEyX291dHB1dHNfMTZTX0JlZUJyZWFkX3d0cmVlLlJEYXRhIikKYGBgCgpSZWFkIGluIG1ldGFkYXRhCgpgYGB7cn0KbWV0YWRhdGE8LXJlYWQuY3N2KCIvVXNlcnMvZ29yZG9uY3VzdGVyL0Rlc2t0b3AvR2l0X1Byb2plY3RzL0JlZUJyZWFkL0RhdGEvQkJfc2FtcGxlLW1ldGFkYXRhLnR4dCIsIHNlcCA9ICJcdCIpCnJvd25hbWVzKG1ldGFkYXRhKTwtbWV0YWRhdGEkWAptZXRhZGF0YSRSZWdpb25fU2l0ZTwtcGFzdGUoIG1ldGFkYXRhJFJlZ2lvbiwgbWV0YWRhdGEkU2l0ZSwgc2VwID0gIiIpCm1ldGFkYXRhJFRyZWF0bWVudF9TaXRlPC1wYXN0ZSggbWV0YWRhdGEkVHJlYXRtZW50LCBtZXRhZGF0YSRTaXRlLCBzZXAgPSAiIikKYGBgCgpDb252ZXJ0IGZpbGVzIHRvIGNvcnJlY3QgZm9ybWF0IGZvciBwaHlsb3NlcSBvYmplY3QgYW5kIHRoZW4gcmVuYW1lIHNhbXBsZXMgaW4gT1RVIHRhYmxlIHRvIG1hdGNoIHRoZSBmb3JtYXQgb2YgdGhlIG1ldGFkYXRhIGZpbGUuIENyZWF0ZSBwaHlsb3NlcSBvYmplY3QgYW5kIHJvb3QgcGh5bG9nZW5ldGljIHRyZWUgZm9yIHVzYWdlIHdpdGggZGlzdGFuY2UgbWV0cmljcyAoZS5nLiwgVW5pZnJhYykuCgpgYGB7cn0KI2Fzc2lnbiBvYmplY3QgdHlwZSB0byBtZXJnZSBpbnRvIHBoeWxvc2VxIG9iamVjdAptZDwtc2FtcGxlX2RhdGEobWV0YWRhdGEpCm90dTwtb3R1X3RhYmxlKHNlcXRhYi5ub2NoaW0sIHRheGFfYXJlX3Jvd3MgPSBGKQp0YXhfdGFiPC10YXhfdGFibGUodGF4YSkKI2NoZWNrIHNhbXBsZSBuYW1lcyBvZiBib3RoIG90dSB0YWJsZSBhbmQgbWV0YWRhdGEKI3JlbW92ZSAuZmFzdHEuZ3ogZnJvbSBvdHUgdGFibGUgbmFtZXMKc2FtcGxlX25hbWVzKG90dSk8LXN0cl9zcGxpdChzYW1wbGVfbmFtZXMob3R1KSwgcGF0dGVybiA9ICIuZmFzdHEuZ3oiLCBzaW1wbGlmeSA9IFQpIFssMV0KI3NpbmNlIHRoZXkgbWF0Y2gsIHlvdSBjYW4gY3JlYXRlIHRoZSBwaHlsb3NlcSBvYmplY3QKYmIxNlNfb3JpZzwtcGh5bG9zZXEobWQsIG90dSwgdGF4X3RhYiwgZml0R1RSJHRyZWUpCgojcm9vdCB0cmVlIGZvciBkaXN0YW5jZSBtZXRyaWNzIGxpa2UgdW5pZnJhYwpzZXQuc2VlZCgxMSkKcGh5X3RyZWUoYmIxNlNfb3JpZyk8LXJvb3QocGh5X3RyZWUoYmIxNlNfb3JpZyksIHNhbXBsZSh0YXhhX25hbWVzKGJiMTZTX29yaWcpLCAxKSwgcmVzb2x2ZS5yb290ID0gVFJVRSkKaXMucm9vdGVkKHBoeV90cmVlKGJiMTZTX29yaWcpKQpgYGAKCiNQcmUtcHJvY2Vzc2luZy4gClJlbmFtZSBPVFUgSURTIHRvIHNvbWV0aGluZyBtb3JlIG1hbmFnZWFibGUuIFdlIHNhdmUgdGhlIEFTQ1Ygc2VxdWVuY2VzIGluIGNhc2Ugd2UgbmVlZCB0aGVtIGxhdGVyIChlLmcuLCBCTEFTVE4gc2VhcmNoZXMpLiBDcmVhdGUgQmFjdGVyaWFsIGFuZCBBcmNoYWVhbCBwaHlsb3NlcSBvYmplY3RzLCBidXQgZmlyc3Qgd2UgcmVtb3ZlIENobG9yb3BsYXN0cy4KCmBgYHtyfQojRXh0cmFjdCBvcmlnaW5hbCBJRHMgZm9yIGZ1dHVyZSByZWZlcmVuY2UuIApzZXFfZGZfd19PVFVJRDwtZGF0YS5mcmFtZShPVFVJRCA9IDE6bnRheGEoYmIxNlNfb3JpZyksIFNlcXVlbmNlID0gdGF4YV9uYW1lcyhiYjE2U19vcmlnKSkKdGF4YV9uYW1lcyhiYjE2U19vcmlnKTwtcGFzdGUoIk9UVV8iICwgMTpudGF4YShiYjE2U19vcmlnKSwgc2VwID0gIiIpCgoKI3JlbW92ZSBjaGxvcm9wbGFzdAojOTc4IGNobG9yb3BsYXN0IG9yIG1pdG9jaG9uZHJpYWwgdGF4YQpiYjE2U19vcmlnX25jPC1zdWJzZXRfdGF4YShiYjE2U19vcmlnLCBGYW1pbHkhPSAiTWl0b2Nob25kcmlhIiB8IGlzLm5hKEZhbWlseSkgJiBPcmRlciE9IkNobG9yb3BsYXN0IiB8IGlzLm5hKE9yZGVyKSkKCgojMTMzNyBiYWN0ZXJpYWwgdGF4YSAtIDkgbm9uLWJhY3RlcmlhIHJlbW92ZWQuIApiYjE2U19iYWM8LXN1YnNldF90YXhhKGJiMTZTX29yaWdfbmMsIEtpbmdkb20gPT0gIkJhY3RlcmlhIikKIzkgYXJjaGFlYQpiYjE2U19hcmNoPC1zdWJzZXRfdGF4YShiYjE2U19vcmlnX25jLCBLaW5nZG9tID09ICJBcmNoYWVhIikKYGBgCgpSZW1vdmUgY29udHJvbCBzYW1wbGVzIGFzIHRoZXJlIGlzIG9ubHkgYXMgc2luZ2xlIHJlcGxpY2F0ZSBvZiBlYWNoLgoKYGBge3J9CnBzX3dvX2NvbnRyb2w8LXN1YnNldF9zYW1wbGVzKGJiMTZTX2JhYywgVHJlYXRtZW50ICE9ICJub25lIikKYGBgCgpFeGFtaW5lIHJhcmVmYWN0aW9uIGN1cnZlcy4gUGxhdGVhdSBpbiBtb3N0IHNhbXBsZXMgdW5kZXIgdGhlIDEuNWsgcmVhZCBtYXJrLgoKYGBge3J9CnJhcmVjdXJ2ZShvdHVfdGFibGUocHNfd29fY29udHJvbCksIHN0ZXA9NTAsIGNleD0wLjUsIG1haW4gPSAiUmFyZWZhY3Rpb24gQ3VydmUiLCB5bGFiPSJSaWNobmVzcyIsIHhsYWI9IlJlYWQgRGVwdGgiKQpgYGAKCmBgYHtyfQpzZXQuc2VlZCgxMSkKc29ydChzYW1wbGVfc3Vtcyhwc193b19jb250cm9sKSkKc3VtbWFyeShzYW1wbGVfc3Vtcyhwc193b19jb250cm9sKSkKc2Qoc2FtcGxlX3N1bXMocHNfd29fY29udHJvbCkpCmJiMTZTX2JhY19yYXJlZnk8LXJhcmVmeV9ldmVuX2RlcHRoKHBzX3dvX2NvbnRyb2wsIHNhbXBsZS5zaXplID0gMTEwMCwgcm5nc2VlZCA9IDE0LCB0cmltT1RVcyA9IFQpCiM1MTcgb3R1cyB3ZXJlIHJlbW92ZWQgZHVyaW5nIHJhcmVmYWN0aW9uLiAKCiNUbyBtb3ZlIGZvcndhcmQsIHdlIGNhbiBoZWxsaW5nZXIgdHJhbnNmb3JtIGFuZCBnbyBmcm9tIHRoZXJlLgpiYjE2U19iYWNfaGVsbGluZ2VyPC10cmFuc2Zvcm1fc2FtcGxlX2NvdW50cyhwc193b19jb250cm9sLCBmdW5jdGlvbih4KSBzcXJ0KHggLyBzdW0oeCkpKQoKI21heGltdW0gbGlrbGlob29kIHBvaW50IGVzdGltYXRlcwpiYjE2U19iYWNfTUw8LSB0cmFuc2Zvcm1fc2FtcGxlX2NvdW50cyhwc193b19jb250cm9sLCBmdW5jdGlvbih4KSB4IC8gc3VtKHgpKQpgYGAKCiNBbHBoYSBEaXZlcnNpdHkKYGBge3J9CnNmMmEgPC0gcGxvdF9yaWNobmVzcyhiYjE2U19iYWNfcmFyZWZ5LCB4ID0gIlNpdGUiLCBtZWFzdXJlcyA9IGMoIlNoYW5ub24iLCAiT2JzZXJ2ZWQiLCAiQ2hhbzEiKSwgY29sb3IgPSAiU2l0ZSIpICsgZ2VvbV9ib3hwbG90KCkgKyBnZ3RpdGxlKCJTYW1wbGluZyBMb2NhdGlvbiIpICsgdGhlbWVfY2xhc3NpYygpICArIHhsYWIoIlNhbXBsaW5nIExvY2F0aW9uIikgICsgdGhlbWUoYXhpcy50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTEyLCBhbmdsZSA9IDQ1LCBoanVzdCA9IDAuNzUpLAogICAgICAgIGF4aXMudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MTQpKQoKc2YyYiA8LSBwbG90X3JpY2huZXNzKGJiMTZTX2JhY19yYXJlZnksIHggPSAiU2l0ZSIsIG1lYXN1cmVzID0gYygiU2hhbm5vbiIsICJPYnNlcnZlZCIsICJDaGFvMSIpLCBjb2xvciA9ICJUcmVhdG1lbnQiKSArIGdlb21fYm94cGxvdCgpICsgZ2d0aXRsZSgiU2FtcGxpbmcgTG9jYXRpb24gYnkgVHJlYXRtZW50IikgKyB0aGVtZV9jbGFzc2ljKCkgKyB5bGFiKCIiKSArIHhsYWIoIlNhbXBsaW5nIExvY2F0aW9uIikgK3RoZW1lKGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xMiwgYW5nbGUgPSA0NSwgaGp1c3QgPSAwLjc1KSwKICAgICAgICBheGlzLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTE0KSkKCnNmMmMgPC1wbG90X3JpY2huZXNzKGJiMTZTX2JhY19yYXJlZnksIHggPSAiU2l0ZSIsIG1lYXN1cmVzID0gYygiU2hhbm5vbiIsICJPYnNlcnZlZCIsICJDaGFvMSIpLCBjb2xvciA9ICJUaW1lcG9pbnQiKSArIGdlb21fYm94cGxvdCgpICsgZ2d0aXRsZSgiU2FtcGxpbmcgTG9jYXRpb24gYnkgU2FtbXBsaW5nIFRpbWUiKSArIHRoZW1lX2NsYXNzaWMoKSArIHhsYWIoIlNhbXBsaW5nIExvY2F0aW9uIikgICt0aGVtZShheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTIsIGFuZ2xlID0gNDUsIGhqdXN0ID0gMC43NSksCiAgICAgICAgYXhpcy50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT0xNCkpCgpzZjJkIDwtcGxvdF9yaWNobmVzcyhiYjE2U19iYWNfcmFyZWZ5LCB4ID0gIlRpbWVwb2ludCIsIG1lYXN1cmVzID0gYygiU2hhbm5vbiIsICJPYnNlcnZlZCIsICJDaGFvMSIpLCBjb2xvciA9ICJUcmVhdG1lbnQiKSArIGdlb21fYm94cGxvdCgpICsgZ2d0aXRsZSgiVHJlYXRtZW50IGJ5IFNhbXBsaW5nIFRpbWUiKSArIHRoZW1lX2NsYXNzaWMoKSArIHlsYWIoIiIpICsgeGxhYigiU2FtcGxpbmcgVGltZXBvaW50IikgICt0aGVtZShheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTIsIGFuZ2xlID0gNDUsIGhqdXN0ID0wLjc1KSwKICAgICAgICBheGlzLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTE0KSkKCnNmMiA8LSBncmlkLmFycmFuZ2Uoc2YyYSwgc2YyYiwgc2YyYywgc2YyZCkKcGxvdChzZjIpCmBgYAoKQ2FsY3VsYXRlIGFscGhhIGRpdmVyc2l0eSBtZXRyaWNzCmBgYHtyfQojY3JlYXRlIGFscGhhIGRpdmVyc2l0eSB0YWJsZSBhbmQgcHJlcCBkYXRhIHRvIGluY2x1ZGUgZ3JvdXBpbmcgY29sdW1ucwpyaWNobmVzc19CQjE2U19iYWM8LWVzdGltYXRlX3JpY2huZXNzKGJiMTZTX2JhY19yYXJlZnksIG1lYXN1cmVzID0gYygiU2hhbm5vbiIsICJPYnNlcnZlZCIsICJDaGFvMSIpKQojYWRkIG1ldGFkYXRhCnJpY2huZXNzX0JCMTZTX2JhYyRTaXRlPC1zYW1wbGVfZGF0YShiYjE2U19iYWNfcmFyZWZ5KSRTaXRlCnJpY2huZXNzX0JCMTZTX2JhYyRUaW1lcG9pbnQ8LXNhbXBsZV9kYXRhKGJiMTZTX2JhY19yYXJlZnkpJFRpbWVwb2ludApyaWNobmVzc19CQjE2U19iYWMkVHJlYXRtZW50PC1zYW1wbGVfZGF0YShiYjE2U19iYWNfcmFyZWZ5KSRUcmVhdG1lbnQKcmljaG5lc3NfQkIxNlNfYmFjJFRyZWF0bWVudF9UaW1lcG9pbnQ8LXNhbXBsZV9kYXRhKGJiMTZTX2JhY19yYXJlZnkpJFRyZWF0bWVudF9UaW1lcG9pbnQKYGBgCgpUZXN0cyBvZiBTaGFubm9uIGRpdmVyc2l0eSAKYGBge3J9CiNBTk9WQSBhbmQgVHVrZXkncyBQVyBjb21wYXJpc29ucwojUnVuIGEgZnVsbCAzIHdheSBBTk9WQSB3aXRoIGludGVyYWN0aW9ucwptb2Q8LWFvdihTaGFubm9uIH4gU2l0ZSAqIFRyZWF0bWVudCAqIFRpbWVwb2ludCwgZGF0YSA9IHJpY2huZXNzX0JCMTZTX2JhYykKI3Jlc2lkdWFscyBsb29rIGZpbmUuIApzaGFwaXJvLnRlc3QobW9kJHJlc2lkdWFscykKaGlzdChtb2QkcmVzaWR1YWxzKQpzdW1tYXJ5KG1vZCkKI1N1bW1hcnkgb2YgbW9kZWwgc2hvd3Mgc2l0ZSBhbmQgdGltZXBvaW50IHNpZ25pZmljYW50IHByZWRpY3RvcnMKI0ludGVyYWN0aW9uIG9mIHNpdGUgYW5kIHRpbWVwb2ludAoKI3Rlc3Qgb2YgaGV0ZXJvZ2VudGl0eSAKbGV2ZW5lVGVzdChTaGFubm9uIH4gU2l0ZSwgZGF0YSA9IHJpY2huZXNzX0JCMTZTX2JhYykKbGV2ZW5lVGVzdChTaGFubm9uIH4gVHJlYXRtZW50LCBkYXRhID0gcmljaG5lc3NfQkIxNlNfYmFjKQpsZXZlbmVUZXN0KFNoYW5ub24gfiBUaW1lcG9pbnQsIGRhdGEgPSByaWNobmVzc19CQjE2U19iYWMpCgojc2lnbmlmaWNhbnQgTGV2ZW5lJ3MgdGVzdCBmb3IgU2l0ZS4gV2Ugd2lsbCBydW4gYW4gYWRkaXRpb25hbCBLcnVza2FsIFdhbGxpcyBmb3Igc2l0ZS4gCmtydXNrYWwudGVzdChTaGFubm9uIH4gU2l0ZSwgZGF0YSA9IHJpY2huZXNzX0JCMTZTX2JhYykKCiNXaGF0IGFib3V0IHBhaXJ3aXNlIGRpZmZlcmVuY2VzIGluIHNpdGUKVHVrZXlIU0QobW9kLCAiU2l0ZSIpCnBsb3QoVHVrZXlIU0QobW9kLCAiU2l0ZSIpLCBsYXM9MSwgY2V4LmF4aXMgPSAwLjQpCgojU2V2ZXJhbCBzaWduaWZpY2FudCBwYWlyd2lzZSBkaWZmZXJlbmNlcyB0byBhY2NvbXBhbnkgdGhlIHNpZ25pZmljYW50IGdsb2JhbCB0ZXN0IGZvciBpbnRlcmFjdGlvbiB0ZXJtLiBXZSBjYW4KVHVrZXlIU0QobW9kLCAiU2l0ZTpUaW1lcG9pbnQiKQpwbG90KFR1a2V5SFNEKG1vZCwgIlNpdGU6VGltZXBvaW50IiksIGxhcz0xLCBjZXguYXhpcyA9IDAuNCkKYGBgCgpUZXN0cyBvZiBDaGFvIDEKYGBge3J9CiNBTk9WQSBhbmQgVHVrZXkncyBQVyBjb21wYXJpc29ucwojUnVuIGEgZnVsbCAzIHdheSBBTk9WQSB3aXRoIGludGVyYWN0aW9ucwptb2Q8LWFvdihDaGFvMSB+IFNpdGUgKiBUcmVhdG1lbnQgKiBUaW1lcG9pbnQsIGRhdGEgPSByaWNobmVzc19CQjE2U19iYWMpCiNyZXNpZHVhbHMgbG9vayBmaW5lLiAKc2hhcGlyby50ZXN0KG1vZCRyZXNpZHVhbHMpCmhpc3QobW9kJHJlc2lkdWFscykKc3VtbWFyeShtb2QpCgpsZXZlbmVUZXN0KENoYW8xIH4gU2l0ZSwgZGF0YSA9IHJpY2huZXNzX0JCMTZTX2JhYykKbGV2ZW5lVGVzdChDaGFvMSB+IFRyZWF0bWVudCwgZGF0YSA9IHJpY2huZXNzX0JCMTZTX2JhYykKbGV2ZW5lVGVzdChDaGFvMSB+IFRpbWVwb2ludCwgZGF0YSA9IHJpY2huZXNzX0JCMTZTX2JhYykKCiNTaXRlIGFuZCB0aGUgaW50ZXJhY3Rpb25zIHdpdGggc2l0ZSBhcmUgc2lnbmlmaWNhbnQuIAoKVHVrZXlIU0QobW9kLCAiU2l0ZSIpCnBsb3QoVHVrZXlIU0QobW9kLCAiU2l0ZSIpLCBsYXM9MSwgY2V4LmF4aXMgPSAwLjQpCmBgYApUZXN0cyBvZiBPYnNlcnZlZCAtIHVuaXF1ZSB0YXhhIGluIGEgc2FtcGxlLiAKYGBge3J9CiNBTk9WQSBhbmQgVHVrZXkncyBQVyBjb21wYXJpc29ucwojUnVuIGEgZnVsbCAzIHdheSBBTk9WQSB3aXRoIGludGVyYWN0aW9ucwptb2Q8LWFvdihPYnNlcnZlZCB+IFNpdGUgKiBUcmVhdG1lbnQgKiBUaW1lcG9pbnQsIGRhdGEgPSByaWNobmVzc19CQjE2U19iYWMpCiNyZXNpZHVhbHMgbG9vayBmaW5lLiAKc2hhcGlyby50ZXN0KG1vZCRyZXNpZHVhbHMpCnN1bW1hcnkobW9kKQpoaXN0KG1vZCRyZXNpZHVhbHMpCgpsZXZlbmVUZXN0KE9ic2VydmVkIH4gU2l0ZSwgZGF0YSA9IHJpY2huZXNzX0JCMTZTX2JhYykKbGV2ZW5lVGVzdChPYnNlcnZlZCB+IFRyZWF0bWVudCwgZGF0YSA9IHJpY2huZXNzX0JCMTZTX2JhYykKbGV2ZW5lVGVzdChPYnNlcnZlZCB+IFRpbWVwb2ludCwgZGF0YSA9IHJpY2huZXNzX0JCMTZTX2JhYykKCiNTdW1tYXJ5IG9mIG1vZGVsIHNob3dzIHNpdGUgYW5kIHRpbWVwb2ludCB0byBiZSBhIHNpZ25pZmljYW50IHByZWRpY3RvciBhcyB3ZWxsIGFzIHRoZSBzaXRlIGludGVyYWN0aW9uIHRlcm1zLgpUdWtleUhTRChtb2QsICJTaXRlIikKcGxvdChUdWtleUhTRChtb2QsICJTaXRlIiksIGxhcz0xLCBjZXguYXhpcyA9IDAuNCkKYGBgCgojQmV0YSBkaXZlcnNpdHkKRnVsbCBtb2RlbCB3aXRoIG5vIHN0cmF0YSBhcmd1bWVudAoKYGBge3J9CiNleHRyYWN0IGRhdGEgZnJvbSBwaHlsb3NlcSBvYmplY3QKdGFiX2Fkb25pczwtZGF0YS5mcmFtZShvdHVfdGFibGUoYmIxNlNfYmFjX01MKSkKc2RfYWRvbmlzPC1kYXRhLmZyYW1lKHNhbXBsZV9kYXRhKGJiMTZTX2JhY19NTCkpCnNkX2Fkb25pcyRUcmVhdG1lbnQgPC1hcy5mYWN0b3Ioc2RfYWRvbmlzJFRyZWF0bWVudCkKc2RfYWRvbmlzJFNpdGUgPC1hcy5mYWN0b3Ioc2RfYWRvbmlzJFNpdGUpCmRpc3RfdzwtcGh5bG9zZXE6OmRpc3RhbmNlKGJiMTZTX2JhY19NTCwgbWV0aG9kID0gICJ3dW5pZnJhYyIpCmRpc3RfdXc8LXBoeWxvc2VxOjpkaXN0YW5jZShiYjE2U19iYWNfTUwsIG1ldGhvZCA9ICAidW5pZnJhYyIpCgojZnVsbCBtb2RlbCB3aXRoIG5vIHN0cmF0YSBhcmd1ZW1udC4gRXNzZW50aWFsbHkgdGhlIGVmZmVjdCBvZiBlYWNoIG1haW4gZWZmZWN0IHdpdGhvdXQgY29udHJvbGxpbmcgZm9yIGFueSBwb3RlbnRpYWwgZ3JvdXBzLiAKCiN3ZWlnaHRlZAphZG9uaXMyKGRpc3RfdyB+ICBTaXRlICogVHJlYXRtZW50ICogVGltZXBvaW50LCBkYXRhPSBzZF9hZG9uaXMsIHBlcm11dGF0aW9ucyA9IDEwMDAwKQojdW53ZWlnaHRlZAphZG9uaXMyKGRpc3RfdXcgfiAgU2l0ZSAqIFRyZWF0bWVudCAqIFRpbWVwb2ludCwgZGF0YT0gc2RfYWRvbmlzLCBwZXJtdXRhdGlvbnMgPSAxMDAwMCkKCiN3aXRoIHN0cmF0YSBhcmd1bWVudAphZG9uaXMyKGRpc3RfdyB+ICBTaXRlICogVHJlYXRtZW50ICogVGltZXBvaW50LCBkYXRhPSBzZF9hZG9uaXMsIHN0cmF0YSA9IHNkX2Fkb25pcyRTaXRlLCBwZXJtdXRhdGlvbnMgPSAxMDAwMCkKYWRvbmlzMihkaXN0X3V3IH4gIFNpdGUgKiBUcmVhdG1lbnQgKiBUaW1lcG9pbnQsIGRhdGE9IHNkX2Fkb25pcywgc3RyYXRhID0gc2RfYWRvbmlzJFNpdGUsIHBlcm11dGF0aW9ucyA9IDEwMDAwKQoKCiMjUFcgYWRvbmlzIHcvIHN0cmF0YSA9IHNpdGUKcGFpcndpc2UuYWRvbmlzMihkaXN0X3V3IH4gVHJlYXRtZW50ICsgVGltZXBvaW50LCBzdHJhdGEgPSAiU2l0ZSIsICBkYXRhPSBzZF9hZG9uaXMsIG5wZXJtID0gMTAwMDApCmBgYApPcmRpbmF0aW9ucwpgYGB7cn0KI3dlaWdodGVkIFVuaWZyYWMKb3JkX25tZHM8LW9yZGluYXRlKHBoeXNlcSA9IGJiMTZTX2JhY19NTCwgbWV0aG9kID0gIk5NRFMiLCBkaXN0YW5jZSA9ICJ3dW5pZnJhYyIpCm9yZF9ubWRzJHN0cmVzcwpwbG90X29yZGluYXRpb24ocGh5c2VxID0gYmIxNlNfYmFjX01MLCBvcmRpbmF0aW9uID0gb3JkX25tZHMsIHR5cGUgPSAiU2FtcGxlcyIsIGNvbG9yID0gIlNpdGUiLCBzaGFwZSA9ICJUcmVhdG1lbnQiICkgKyB0aGVtZV9jbGFzc2ljKCkgKyBnZ3RpdGxlKCJXZWlnaHRlZCBVbmlmcmFjIE5NRFMiKSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIHNpemUgPSAxOCkpICsgZ2VvbV9wb2ludChzaXplID0gMykgKyB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwgYXhpcy50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT0xNCkpCiNnZ3NhdmUoIi4uLy4uL1dyaXRpbmcvRmluYWxfRmlncy9XZWlnaHRlZF9VbmlmcmFjX05NRFMuZXBzIikKI3N0cm9uZ2VzdCBncm91cGluZyBieSBTaXRlLiBUaW1lIHBvaW50IGFsc28gaGFzIGEgc21hbGxlciBlZmZlY3QsIGJ1dCB0aGVzZSBncm91cGluZ3MgYXJlIG1vcmUgY2xlYXIgdGhhbiBpbiB0aGUgQ0FQIG9yZGluYXRpb24uIFRoZXJlIGFyZSBzZXZlcmFsIG91dGxpZXIgc2FtcGxlcyB0aGF0IG9yZGluYXRlIGZhciB0byB0aGUgcmlnaHQgb24gdGhlIE5NRFMxIGF4aXMuIAoKI3Vud2VpZ2h0ZWQgVW5pZnJhYwpvcmRfbm1kczwtb3JkaW5hdGUocGh5c2VxID0gYmIxNlNfYmFjX01MLCBtZXRob2QgPSAiTk1EUyIsIGRpc3RhbmNlID0gInVuaWZyYWMiKQpvcmRfbm1kcyRzdHJlc3MKcGxvdF9vcmRpbmF0aW9uKHBoeXNlcSA9IGJiMTZTX2JhY19NTCwgb3JkaW5hdGlvbiA9IG9yZF9ubWRzLCB0eXBlID0gIlNhbXBsZXMiLCBjb2xvciA9ICJTaXRlIiwgc2hhcGUgPSAiVHJlYXRtZW50IiApICsgdGhlbWVfY2xhc3NpYygpICsgZ2d0aXRsZSgiVW53ZWlnaHRlZCBVbmlmcmFjIE5NRFMiKSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIHNpemUgPSAxOCkpICsgZ2VvbV9wb2ludChzaXplID0gMykgKyB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwgYXhpcy50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT0xNCkpCiNnZ3NhdmUoIi4uLy4uL1dyaXRpbmcvRmluYWxfRmlncy9VbndlaWdodGVkX1VuaWZyYWNfTk1EUy5lcHMiKQoKCmBgYAoKClNhbXBsaW5nIHRpbWUgMiAocG9zdCB0cmVhdG1lbnQpCmBgYHtyfQojcG9zdC10cmVhdG1lbnQgc2FtcGxlcwpiYjE2U19iYWNfTUxfQjwtc3Vic2V0X3NhbXBsZXMoYmIxNlNfYmFjX01MLCBUaW1lcG9pbnQgPT0gIkIiKQoKI2V4dHJhY3QgZGF0YSBmcm9tIHBoeWxvc2VxIG9iamVjdCBmb3IgcG9zdC10cmVhdG1lbnQKc2RfYWRvbmlzPC1kYXRhLmZyYW1lKHNhbXBsZV9kYXRhKGJiMTZTX2JhY19NTF9CKSkKc2RfYWRvbmlzJFRyZWF0bWVudCA8LWFzLmZhY3RvcihzZF9hZG9uaXMkVHJlYXRtZW50KQpzZF9hZG9uaXMkU2l0ZSA8LWFzLmZhY3RvcihzZF9hZG9uaXMkU2l0ZSkKZGlzdF93YjwtcGh5bG9zZXE6OmRpc3RhbmNlKGJiMTZTX2JhY19NTF9CLCBtZXRob2QgPSAgInd1bmlmcmFjIikKZGlzdF91d2I8LXBoeWxvc2VxOjpkaXN0YW5jZShiYjE2U19iYWNfTUxfQiwgbWV0aG9kID0gICJ1bmlmcmFjIikKCgojd2l0aCBzdHJhdGEgYXJndW1lbnQKYWRvbmlzMihkaXN0X3diIH4gIFNpdGUgKiBUcmVhdG1lbnQsIGRhdGE9IHNkX2Fkb25pcywgc3RyYXRhID0gc2RfYWRvbmlzJFNpdGUsIHBlcm11dGF0aW9ucyA9IDEwMDAwKQphZG9uaXMyKGRpc3RfdXdiIH4gIFNpdGUgKiBUcmVhdG1lbnQsIGRhdGE9IHNkX2Fkb25pcywgc3RyYXRhID0gc2RfYWRvbmlzJFNpdGUsIHBlcm11dGF0aW9ucyA9IDEwMDAwKQoKcGFpcndpc2UuYWRvbmlzMihkaXN0X3V3YiB+VHJlYXRtZW50LCBzdHJhdGEgPSAiU2l0ZSIsIGRhdGEgPSBzZF9hZG9uaXMsIG5wZXJtID0gMTAwMDApCgojb3JkaW5hdGlvbnMKI3dlaWdodGVkIFVuaWZyYWMKb3JkX25tZHM8LW9yZGluYXRlKHBoeXNlcSA9IGJiMTZTX2JhY19NTF9CLCBtZXRob2QgPSAiTk1EUyIsIGRpc3RhbmNlID0gInd1bmlmcmFjIikKb3JkX25tZHMkc3RyZXNzCnBsb3Rfb3JkaW5hdGlvbihwaHlzZXEgPSBiYjE2U19iYWNfTUxfQiwgb3JkaW5hdGlvbiA9IG9yZF9ubWRzLCB0eXBlID0gIlNhbXBsZXMiLCBjb2xvciA9ICJTaXRlIiwgc2hhcGUgPSAiVHJlYXRtZW50IiApICsgdGhlbWVfY2xhc3NpYygpICsgZ2d0aXRsZSgiV2VpZ2h0ZWQgVW5pZnJhYyBOTURTIikgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBzaXplID0gMTgpKSArIGdlb21fcG9pbnQoc2l6ZSA9IDMpCmdnc2F2ZSgiLi4vLi4vV3JpdGluZy9GaW5hbF9GaWdzL1RpbWUyX1dlaWdodGVkX1VuaWZyYWNfTk1EUy5wZGYiKQojc3Ryb25nZXN0IGdyb3VwaW5nIGJ5IFNpdGUuIFRpbWUgcG9pbnQgYWxzbyBoYXMgYSBzbWFsbGVyIGVmZmVjdCwgYnV0IHRoZXNlIGdyb3VwaW5ncyBhcmUgbW9yZSBjbGVhciB0aGFuIGluIHRoZSBDQVAgb3JkaW5hdGlvbi4gVGhlcmUgYXJlIHNldmVyYWwgb3V0bGllciBzYW1wbGVzIHRoYXQgb3JkaW5hdGUgZmFyIHRvIHRoZSByaWdodCBvbiB0aGUgTk1EUzEgYXhpcy4gCgojdW53ZWlnaHRlZCBVbmlmcmFjCm9yZF9ubWRzPC1vcmRpbmF0ZShwaHlzZXEgPSBiYjE2U19iYWNfTUxfQiwgbWV0aG9kID0gIk5NRFMiLCBkaXN0YW5jZSA9ICJ1bmlmcmFjIikKb3JkX25tZHMkc3RyZXNzCnBsb3Rfb3JkaW5hdGlvbihwaHlzZXEgPSBiYjE2U19iYWNfTUxfQiwgb3JkaW5hdGlvbiA9IG9yZF9ubWRzLCB0eXBlID0gIlNhbXBsZXMiLCBjb2xvciA9ICJTaXRlIiwgc2hhcGUgPSAiVHJlYXRtZW50IiApICsgdGhlbWVfY2xhc3NpYygpICsgZ2d0aXRsZSgiVW53ZWlnaHRlZCBVbmlmcmFjIE5NRFMiKSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIHNpemUgPSAxOCkpICsgZ2VvbV9wb2ludChzaXplID0gMykKZ2dzYXZlKCIuLi8uLi9Xcml0aW5nL0ZpbmFsX0ZpZ3MvVGltZTJfVW53ZWlnaHRlZF9VbmlmcmFjX05NRFMucGRmIikKCmBgYAoKY3JlYXRlIHRheGEgYmFyIHBsb3QgdG8gZGlzcGxheSBtYWtldXAKYGBge3J9CnNvcnQodGFibGUoZGF0YS5mcmFtZSh0YXhfdGFibGUoYmIxNlNfYmFjX3JhcmVmeSkpJFBoeWx1bSksIGRlY3JlYXNpbmcgPSBUUlVFKQpsZW5ndGgodW5pcXVlKGRhdGEuZnJhbWUodGF4X3RhYmxlKGJiMTZTX2JhY19yYXJlZnkpKSRQaHlsdW0pKQoKc29ydCh0YWJsZShkYXRhLmZyYW1lKHRheF90YWJsZShiYjE2U19iYWNfcmFyZWZ5KSkkT3JkZXIpLCBkZWNyZWFzaW5nID0gVFJVRSkKbGVuZ3RoKHVuaXF1ZShkYXRhLmZyYW1lKHRheF90YWJsZShiYjE2U19iYWNfcmFyZWZ5KSkkT3JkZXIpKQoKc29ydCh0YWJsZShkYXRhLmZyYW1lKHRheF90YWJsZShiYjE2U19iYWNfcmFyZWZ5KSkkRmFtaWx5KSwgZGVjcmVhc2luZyA9IFRSVUUpCmxlbmd0aCh1bmlxdWUoZGF0YS5mcmFtZSh0YXhfdGFibGUoYmIxNlNfYmFjX3JhcmVmeSkpJEZhbWlseSkpCgpwbG90X2JhcihzdWJzZXRfc2FtcGxlcyhiYjE2U19iYWNfcmFyZWZ5LCBUaW1lcG9pbnQgPT0gIkEiKSwgZmlsbCA9ICJQaHlsdW0iKSAgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xfdmVjdG9yKSArIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSsgY29vcmRfZmxpcCgpCmdnc2F2ZSgiLi4vLi4vV3JpdGluZy9GaW5hbF9GaWdzL3RheGFiYXJBLnBkZiIpCgpwbG90X2JhcihzdWJzZXRfc2FtcGxlcyhiYjE2U19iYWNfcmFyZWZ5LCBUaW1lcG9pbnQgPT0gIkIiKSwgZmlsbCA9ICJQaHlsdW0iKSAgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xfdmVjdG9yKSArIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSsgY29vcmRfZmxpcCgpCmdnc2F2ZSgiLi4vLi4vV3JpdGluZy9GaW5hbF9GaWdzL3RheGFiYXJCLnBkZiIpCgoKYGBgCgoKI0NvcmUgYW5hbHlzaXMKCmBgYHtyfQojY3JlYXRlIHN1cGVyIGxvbmcgY29sb3IgdmVjdG9yCmNvbF92ZWN0b3IgPC0gYygiIzAwMDAwMCIsICIjRkZGRjAwIiwgIiMxQ0U2RkYiLCAiI0ZGMzRGRiIsICIjRkY0QTQ2IiwgIiMwMDg5NDEiLCAiIzAwNkZBNiIsICIjQTMwMDU5IiwKICAgICAgICAiI0ZGREJFNSIsICIjN0E0OTAwIiwgIiMwMDAwQTYiLCAiIzYzRkZBQyIsICIjQjc5NzYyIiwgIiMwMDRENDMiLCAiIzhGQjBGRiIsICIjOTk3RDg3IiwKICAgICAgICAiIzVBMDAwNyIsICIjODA5NjkzIiwgIiNGRUZGRTYiLCAiIzFCNDQwMCIsICIjNEZDNjAxIiwgIiMzQjVERkYiLCAiIzRBM0I1MyIsICIjRkYyRjgwIiwKICAgICAgICAiIzYxNjE1QSIsICIjQkEwOTAwIiwgIiM2Qjc5MDAiLCAiIzAwQzJBMCIsICIjRkZBQTkyIiwgIiNGRjkwQzkiLCAiI0I5MDNBQSIsICIjRDE2MTAwIiwKICAgICAgICAiI0RERUZGRiIsICIjMDAwMDM1IiwgIiM3QjRGNEIiLCAiI0ExQzI5OSIsICIjMzAwMDE4IiwgIiMwQUE2RDgiLCAiIzAxMzM0OSIsICIjMDA4NDZGIiwKICAgICAgICAiIzM3MjEwMSIsICIjRkZCNTAwIiwgIiNDMkZGRUQiLCAiI0EwNzlCRiIsICIjQ0MwNzQ0IiwgIiNDMEI5QjIiLCAiI0MyRkY5OSIsICIjMDAxRTA5IiwKICAgICAgICAiIzAwNDg5QyIsICIjNkYwMDYyIiwgIiMwQ0JENjYiLCAiI0VFQzNGRiIsICIjNDU2RDc1IiwgIiNCNzdCNjgiLCAiIzdBODdBMSIsICIjNzg4RDY2IiwKICAgICAgICAiIzg4NTU3OCIsICIjRkFEMDlGIiwgIiNGRjhBOUEiLCAiI0QxNTdBMCIsICIjQkVDNDU5IiwgIiM0NTY2NDgiLCAiIzAwODZFRCIsICIjODg2RjRDIiwKICAgICAgICAKICAgICAgICAiIzM0MzYyRCIsICIjQjRBOEJEIiwgIiMwMEE2QUEiLCAiIzQ1MkMyQyIsICIjNjM2Mzc1IiwgIiNBM0M4QzkiLCAiI0ZGOTEzRiIsICIjOTM4QTgxIiwKICAgICAgICAiIzU3NTMyOSIsICIjMDBGRUNGIiwgIiNCMDVCNkYiLCAiIzhDRDBGRiIsICIjM0I5NzAwIiwgIiMwNEY3NTciLCAiI0M4QTFBMSIsICIjMUU2RTAwIiwKICAgICAgICAiIzc5MDBENyIsICIjQTc3NTAwIiwgIiM2MzY3QTkiLCAiI0EwNTgzNyIsICIjNkIwMDJDIiwgIiM3NzI2MDAiLCAiI0Q3OTBGRiIsICIjOUI5NzAwIiwKICAgICAgICAiIzU0OUU3OSIsICIjRkZGNjlGIiwgIiMyMDE2MjUiLCAiIzcyNDE4RiIsICIjQkMyM0ZGIiwgIiM5OUFEQzAiLCAiIzNBMjQ2NSIsICIjOTIyMzI5IiwKICAgICAgICAiIzVCNDUzNCIsICIjRkRFOERDIiwgIiM0MDRFNTUiLCAiIzAwODlBMyIsICIjQ0I3RTk4IiwgIiNBNEU4MDQiLCAiIzMyNEU3MiIsICIjNkEzQTRDIiwKICAgICAgICAiIzgzQUI1OCIsICIjMDAxQzFFIiwgIiNEMUY3Q0UiLCAiIzAwNEIyOCIsICIjQzhEMEY2IiwgIiNBM0E0ODkiLCAiIzgwNkM2NiIsICIjMjIyODAwIiwKICAgICAgICAiI0JGNTY1MCIsICIjRTgzMDAwIiwgIiM2Njc5NkQiLCAiI0RBMDA3QyIsICIjRkYxQTU5IiwgIiM4QURCQjQiLCAiIzFFMDIwMCIsICIjNUI0RTUxIiwKICAgICAgICAiI0M4OTVDNSIsICIjMzIwMDMzIiwgIiNGRjY4MzIiLCAiIzY2RTFEMyIsICIjQ0ZDREFDIiwgIiNEMEFDOTQiLCAiIzdFRDM3OSIsICIjMDEyQzU4IiwKICAgICAgICAKICAgICAgICAiIzdBN0JGRiIsICIjRDY4RTAxIiwgIiMzNTMzMzkiLCAiIzc4QUZBMSIsICIjRkVCMkM2IiwgIiM3NTc5N0MiLCAiIzgzNzM5MyIsICIjOTQzQTREIiwKICAgICAgICAiI0I1RjRGRiIsICIjRDJEQ0Q1IiwgIiM5NTU2QkQiLCAiIzZBNzE0QSIsICIjMDAxMzI1IiwgIiMwMjUyNUYiLCAiIzBBQTNGNyIsICIjRTk4MTc2IiwKICAgICAgICAiI0RCRDVERCIsICIjNUVCQ0QxIiwgIiMzRDRGNDQiLCAiIzdFNjQwNSIsICIjMDI2ODRFIiwgIiM5NjJCNzUiLCAiIzhEODU0NiIsICIjOTY5NUM1IiwKICAgICAgICAiI0U3NzNDRSIsICIjRDg2QTc4IiwgIiMzRTg5QkUiLCAiI0NBODM0RSIsICIjNTE4QTg3IiwgIiM1QjExM0MiLCAiIzU1ODEzQiIsICIjRTcwNEM0IiwKICAgICAgICAiIzAwMDA1RiIsICIjQTk3Mzk5IiwgIiM0QjgxNjAiLCAiIzU5NzM4QSIsICIjRkY1REE3IiwgIiNGN0M5QkYiLCAiIzY0MzEyNyIsICIjNTEzQTAxIiwKICAgICAgICAiIzZCOTRBQSIsICIjNTFBMDU4IiwgIiNBNDVCMDIiLCAiIzFEMTcwMiIsICIjRTIwMDI3IiwgIiNFN0FCNjMiLCAiIzRDNjAwMSIsICIjOUM2OTY2IiwKICAgICAgICAiIzY0NTQ3QiIsICIjOTc5NzlFIiwgIiMwMDZBNjYiLCAiIzM5MTQwNiIsICIjRjRENzQ5IiwgIiMwMDQ1RDIiLCAiIzAwNkMzMSIsICIjRERCNkQwIiwKICAgICAgICAiIzdDNjU3MSIsICIjOUZCMkE0IiwgIiMwMEQ4OTEiLCAiIzE1QTA4QSIsICIjQkM2NUU5IiwgIiNGRkZGRkUiLCAiI0M2REM5OSIsICIjMjAzQjNDIiwKICAgICAgICAiIzY3MTE5MCIsICIjNkIzQTY0IiwgIiNGNUUxRkYiLCAiI0ZGQTBGMiIsICIjQ0NBQTM1IiwgIiMzNzQ1MjciLCAiIzhCQjQwMCIsICIjNzk3ODY4IiwKICAgICAgICAiI0M2MDA1QSIsICIjM0IwMDBBIiwgIiNDODYyNDAiLCAiIzI5NjA3QyIsICIjNDAyMzM0IiwgIiM3RDVBNDQiLCAiI0NDQjg3QyIsICIjQjg4MTgzIiwKICAgICAgICAiI0FBNTE5OSIsICIjQjVENkMzIiwgIiNBMzg0NjkiLCAiIzlGOTRGMCIsICIjQTc0NTcxIiwgIiNCODk0QTYiLCAiIzcxQkI4QyIsICIjMDBCNDMzIiwKICAgICAgICAiIzc4OUVDOSIsICIjNkQ4MEJBIiwgIiM5NTNGMDAiLCAiIzVFRkYwMyIsICIjRTRGRkZDIiwgIiMxQkUxNzciLCAiI0JDQjFFNSIsICIjNzY5MTJGIiwKICAgICAgICAiIzAwMzEwOSIsICIjMDA2MENEIiwgIiNEMjAwOTYiLCAiIzg5NTU2MyIsICIjMjkyMDFEIiwgIiM1QjMyMTMiLCAiI0E3NkY0MiIsICIjODk0MTJFIiwKICAgICAgICAiIzFBM0EyQSIsICIjNDk0QjVBIiwgIiNBODhDODUiLCAiI0Y0QUJBQSIsICIjQTNGM0FCIiwgIiMwMEM2QzgiLCAiI0VBOEI2NiIsICIjOTU4QTlGIiwKICAgICAgICAiI0JEQzlEMiIsICIjOUZBMDY0IiwgIiNCRTQ3MDAiLCAiIzY1ODE4OCIsICIjODNBNDg1IiwgIiM0NTNDMjMiLCAiIzQ3Njc1RCIsICIjM0EzRjAwIiwKICAgICAgICAiIzA2MTIwMyIsICIjREZGQjcxIiwgIiM4NjhFN0UiLCAiIzk4RDA1OCIsICIjNkM4RjdEIiwgIiNEN0JGQzIiLCAiIzNDM0U2RSIsICIjRDgzRDY2IiwKICAgICAgICAiIzJGNUQ5QiIsICIjNkM1RTQ2IiwgIiNEMjVCODgiLCAiIzVCNjU2QyIsICIjMDBCNTdGIiwgIiM1NDVDNDYiLCAiIzg2NjA5NyIsICIjMzY1RDI1IiwKICAgICAgICAiIzI1MkY5OSIsICIjMDBDQ0ZGIiwgIiM2NzRFNjAiLCAiI0ZDMDA5QyIsICIjOTI4OTZCIikKYGBgCgpjYWxjdWxhdGUgY29yZSBhdCBnZW51cyBhbmQgYXN2IGxldmVsIHVzaW5nIHJhcmVmaWVkIGRhdGEKYGBge3J9CiNjYWxjdWxhdGUgY29yZSBhdCBnZW51cyBsZXZlbAojMzI1IGdlbmVyYQpiYjE2U19iYWNfcmFyZWZ5X3RheF9nZW51czwtdGF4X2dsb20ocGh5c2VxID0gYmIxNlNfYmFjX3JhcmVmeSwgdGF4cmFuayA9ICJHZW51cyIsIE5Bcm0gPSBGKQojY2FsY3VsYXRlIGNvcmUKY29yZV9nZW51czwtdGF4YV9jb3JlKHBoeWxvc2VxX29iaiA9IGJiMTZTX2JhY19yYXJlZnlfdGF4X2dlbnVzLCB0cmVhdG1lbnQgPSAiU2l0ZSIsIGZyZXF1ZW5jeSA9IDEsIGFidW5kYW5jZV90aHJlc2hvbGQgPSAwLjAwMDEpCmNvcmVfZ2VudXM8LXRheGFfY29yZShwaHlsb3NlcV9vYmogPSBjb3JlX2dlbnVzLCBmcmVxdWVuY3kgPSAwLjUsIGFidW5kYW5jZV90aHJlc2hvbGQgPSAwLjAwMDEpCgpvdHVfZ2VudXNfY29yZSA8LSBkYXRhLmZyYW1lKG90dV90YWJsZShjb3JlX2dlbnVzKSkKdGF4X2dlbnVzX2NvcmUgPC0gZGF0YS5mcmFtZSh0YXhfdGFibGUoY29yZV9nZW51cykpCnNhbXBfZGF0YV9nZW51c19jb3JlIDwtIGRhdGEuZnJhbWUoc2FtcGxlX2RhdGEoY29yZV9nZW51cykpCgp3cml0ZS5jc3Yob3R1X2dlbnVzX2NvcmUsICIvVXNlcnMvZ29yZG9uY3VzdGVyL0Rlc2t0b3AvR2l0X1Byb2plY3RzL0JlZUJyZWFkL1dyaXRpbmcvb3R1X2dlbnVzX2NvcmUuY3N2IikKd3JpdGUuY3N2KHRheF9nZW51c19jb3JlLCAiL1VzZXJzL2dvcmRvbmN1c3Rlci9EZXNrdG9wL0dpdF9Qcm9qZWN0cy9CZWVCcmVhZC9Xcml0aW5nL3RheF9nZW51c19jb3JlLmNzdiIpCndyaXRlLmNzdihzYW1wX2RhdGFfZ2VudXNfY29yZSwgIi9Vc2Vycy9nb3Jkb25jdXN0ZXIvRGVza3RvcC9HaXRfUHJvamVjdHMvQmVlQnJlYWQvV3JpdGluZy9zYW1wX2RhdGFfZ2VudXNfY29yZS5jc3YiKQoKI3RhYmxlIHRheG9ub21pYyBpbmZvIG9mIGNvcmUgZ2VuZXJhCnRhYmxlKGRhdGEuZnJhbWUodGF4X3RhYmxlKGNvcmVfZ2VudXMpKSRPcmRlcikKdGFibGUoZGF0YS5mcmFtZSh0YXhfdGFibGUoY29yZV9nZW51cykpJEdlbnVzKQojcGVyY2VudCBvZiBnZW5lcmEgYXNzaWduZWQgdG8gY29yZQoxNC8zMjUKI3BlcmNlbnQgb2YgcmVhZHMgYWNjb3VudGVkIGZvciBieSB0aGUgY29yZSBnZW5lcmEKc3VtKHNhbXBsZV9zdW1zKGNvcmVfZ2VudXMpKS9zdW0oc2FtcGxlX3N1bXMoYmIxNlNfYmFjX3JhcmVmeSkpCgojZXh0cmFjdCBzZXF1ZW5jZSBvZiBjb3JlIGdlbmVyYSBhbmQgZXhwb3J0IGZvciB0cmVlIGJ1aWxkaW5nIApjb3JlX2dlbnVzX25hbWVzPC1yb3duYW1lcyh0YXhfdGFibGUoY29yZV9nZW51cykpCmNvcmVfZ2VuZXJhX3JlcF9zZXE8LXNlcV9kZl93X09UVUlEW3NlcV9kZl93X09UVUlEJE9UVUlEICVpbiUgc3RyX3NwbGl0KGNvcmVfZ2VudXNfbmFtZXMsIHBhdHRlcm4gPSAiXyIsIDIsIHNpbXBsaWZ5ID0gVClbLDJdLF0gCnRheGFfZGY8LWRhdGEuZnJhbWUodGF4YSkKY29yZV9nZW5lcmFfdGF4IDwtIHRheGFfZGZbcm93bmFtZXModGF4YV9kZikgJWluJSBjb3JlX2dlbmVyYV9yZXBfc2VxJFNlcXVlbmNlLF0KY29yZV9nZW5lcmFfdGF4JFNlcXVlbmNlIDwtIHJvd25hbWVzKGNvcmVfZ2VuZXJhX3RheCkKbWVyZ2VkX3RheF9jb3JlX2dlbmVyYV9yZXBfc2VxPC1mdWxsX2pvaW4oY29yZV9nZW5lcmFfdGF4LCBjb3JlX2dlbmVyYV9yZXBfc2VxKQoKI3dyaXRlLmNzdihtZXJnZWRfdGF4X2NvcmVfZ2VuZXJhX3JlcF9zZXEsICIvVXNlcnMvZ29yZG9uY3VzdGVyL0Rlc2t0b3AvR2l0X1Byb2plY3RzL0JlZUJyZWFkL1dyaXRpbmcvQ29yZV9nZW5lcmFfdGF4YV9yZXBfc2VxLmNzdiIpCiN3cml0ZS5jc3YoY29yZV9nZW5lcmFfcmVwX3NlcSwgIi9Vc2Vycy9nb3Jkb25jdXN0ZXIvRGVza3RvcC9HaXRfUHJvamVjdHMvQmVlQnJlYWQvV3JpdGluZy9Db3JlX0dlbmVyYV9SZXBfU2Vxcy5jc3YiKQojd3JpdGUuY3N2KGNvcmVfZ2VuZXJhX3RheCwgIi9Vc2Vycy9nb3Jkb25jdXN0ZXIvRGVza3RvcC9HaXRfUHJvamVjdHMvQmVlQnJlYWQvV3JpdGluZy9Db3JlX0dlbmVyYV90YXguY3N2IikKYGBgCgpDb3JlIEdlbnVzCmBgYHtyfQojY29yZSBhc3YgYWRvbmlzCnRhYl9hZG9uaXM8LWRhdGEuZnJhbWUob3R1X3RhYmxlKGNvcmVfZ2VudXMpKQpzZF9hZG9uaXM8LWRhdGEuZnJhbWUoc2FtcGxlX2RhdGEoY29yZV9nZW51cykpCnNkX2Fkb25pcyRUcmVhdG1lbnQgPC1hcy5mYWN0b3Ioc2RfYWRvbmlzJFRyZWF0bWVudCkKc2RfYWRvbmlzJFNpdGUgPC1hcy5mYWN0b3Ioc2RfYWRvbmlzJFNpdGUpCmRpc3RfY29yZV93X2dlbnVzPC1waHlsb3NlcTo6ZGlzdGFuY2UoY29yZV9nZW51cywgbWV0aG9kID0gICJ3dW5pZnJhYyIpCmRpc3RfY29yZV91d19nZW51czwtcGh5bG9zZXE6OmRpc3RhbmNlKGNvcmVfZ2VudXMsIG1ldGhvZCA9ICAidW5pZnJhYyIpCgojd2VpZ2h0ZWQgdW5pZnJhYwphZG9uaXMyKGRpc3RfY29yZV93X2dlbnVzIH4gIFNpdGUgKiBUcmVhdG1lbnQgKiBUaW1lcG9pbnQsIGRhdGE9IHNkX2Fkb25pcywgc3RyYXRhID0gc2RfYWRvbmlzJFNpdGUsIHBlcm11dGF0aW9ucyA9IDEwMDApCiN1bndlaWdodGVkIHVuaWZyYWMKYWRvbmlzMihkaXN0X2NvcmVfdXdfZ2VudXMgfiAgU2l0ZSAqIFRyZWF0bWVudCAqIFRpbWVwb2ludCwgZGF0YT0gc2RfYWRvbmlzLCBzdHJhdGEgPSBzZF9hZG9uaXMkU2l0ZSwgcGVybXV0YXRpb25zID0gMTAwMCkKCiNvcmRpbmF0aW9ucwojd2VpZ2h0ZWQgVW5pZnJhYwpvcmRfbm1kczwtb3JkaW5hdGUocGh5c2VxID0gY29yZV9nZW51cywgbWV0aG9kID0gIk5NRFMiLCBkaXN0YW5jZSA9ICJ3dW5pZnJhYyIpCm9yZF9ubWRzJHN0cmVzcwpwbG90X29yZGluYXRpb24ocGh5c2VxID0gY29yZV9nZW51cywgb3JkaW5hdGlvbiA9IG9yZF9ubWRzLCB0eXBlID0gIlNhbXBsZXMiLCBjb2xvciA9ICJTaXRlIiwgc2hhcGUgPSAiVHJlYXRtZW50IiApICsgdGhlbWVfY2xhc3NpYygpICsgZ2d0aXRsZSgiQ29yZSBHZW5lcmEgV2VpZ2h0ZWQgVW5pZnJhYyBOTURTIikgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBzaXplID0gMTgpKSArIGdlb21fcG9pbnQoc2l6ZSA9IDMpICArIHRoZW1lKGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpLCBheGlzLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTE0KSkKZ2dzYXZlKCIuLi8uLi9Xcml0aW5nL0ZpbmFsX0ZpZ3MvQ29yZUdlbnVzX1dlaWdodGVkX1VuaWZyYWNfTk1EUy5lcHMiKQojc3Ryb25nZXN0IGdyb3VwaW5nIGJ5IFNpdGUuIFRpbWUgcG9pbnQgYWxzbyBoYXMgYSBzbWFsbGVyIGVmZmVjdCwgYnV0IHRoZXNlIGdyb3VwaW5ncyBhcmUgbW9yZSBjbGVhciB0aGFuIGluIHRoZSBDQVAgb3JkaW5hdGlvbi4gVGhlcmUgYXJlIHNldmVyYWwgb3V0bGllciBzYW1wbGVzIHRoYXQgb3JkaW5hdGUgZmFyIHRvIHRoZSByaWdodCBvbiB0aGUgTk1EUzEgYXhpcy4gCgojdW53ZWlnaHRlZCBVbmlmcmFjCm9yZF9ubWRzPC1vcmRpbmF0ZShwaHlzZXEgPSBjb3JlX2dlbnVzLCBtZXRob2QgPSAiTk1EUyIsIGRpc3RhbmNlID0gInVuaWZyYWMiKQpvcmRfbm1kcyRzdHJlc3MKcGxvdF9vcmRpbmF0aW9uKHBoeXNlcSA9IGNvcmVfZ2VudXMsIG9yZGluYXRpb24gPSBvcmRfbm1kcywgdHlwZSA9ICJTYW1wbGVzIiwgY29sb3IgPSAiU2l0ZSIsIHNoYXBlID0gIlRyZWF0bWVudCIgKSArIHRoZW1lX2NsYXNzaWMoKSArIGdndGl0bGUoIkNvcmUgR2VuZXJhIFVud2VpZ2h0ZWQgVW5pZnJhYyBOTURTIikgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBzaXplID0gMTgpKSArIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgdGhlbWUoYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksIGF4aXMudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MTQpKQpnZ3NhdmUoIi4uLy4uL1dyaXRpbmcvRmluYWxfRmlncy9Db3JlR2VudXNfVW53ZWlnaHRlZF9VbmlmcmFjX05NRFMuZXBzIikKYGBgCgoKVmlzdWFsaXphdGlvbiBvZiBjb3JlIG1pY3JvYmlvbWUgdXNpbmcgYmFycGxvdApgYGB7cn0KI3B1bGwgb3V0IGNvcmUgZ2VuZXJhIG5hbWVzCmNvcmVfZ2VudXNfbmFtZXM8LXJvd25hbWVzKHRheF90YWJsZShjb3JlX2dlbnVzKSkKZ2VudXNfT1RVX3RhYmxlPC1kYXRhLmZyYW1lKHQob3R1X3RhYmxlKGJiMTZTX2JhY19yYXJlZnlfdGF4X2dlbnVzKSkpCiNjaGVjayBvcmllbnRhdGlvbiBvZiBvdHUgdGFibGUKcm93bmFtZXMoZ2VudXNfT1RVX3RhYmxlKQojYWRkIGNvbHVtbnMgY29ycmVzcG9uZGluZyB0byBjb3JlIHN0YXR1cywgJSBzaXRlcywgJSByZWFkcwpnZW51c19PVFVfdGFibGUkQ29yZSA8LSBOQSAKZm9yKGkgaW4gMTpucm93KGdlbnVzX09UVV90YWJsZSkpewogIGlmKHJvd25hbWVzKGdlbnVzX09UVV90YWJsZSlbaV0gJWluJSBjb3JlX2dlbnVzX25hbWVzID09IFQpewogIGdlbnVzX09UVV90YWJsZVtpLF0kQ29yZSA8LSAiQ29yZSIKICB9IGVsc2V7CiAgZ2VudXNfT1RVX3RhYmxlW2ksXSRDb3JlIDwtICJOb25Db3JlIgogIH0KfQoKI1ByZXZhbGVuY2UgY29sdW1uCmdlbnVzX09UVV90YWJsZSRwcmV2IDwtIE5BCmZvcihpIGluIDE6bnJvdyhnZW51c19PVFVfdGFibGUpKXsKICBnZW51c19PVFVfdGFibGVbaSxdJHByZXY8LXRhYmxlKGdlbnVzX09UVV90YWJsZVtpLCgxOjY5KV0gPiAwKVsiVFJVRSJdLyA2OX0KCiNwcm9wb3J0aW9uYWwgYWJ1bmRhbmNlCmdlbnVzX09UVV90YWJsZSRhYnVuZCA8LSBOQQogIGZvcihpIGluIDE6bnJvdyhnZW51c19PVFVfdGFibGUpKXsKICBnZW51c19PVFVfdGFibGVbaSxdJGFidW5kIDwtIHJvd1N1bXMoZ2VudXNfT1RVX3RhYmxlW2ksYygxOjY5KV0pL3N1bShjb2xTdW1zKGdlbnVzX09UVV90YWJsZVssYygxOjY5KV0pKQogIH0KCmRhdDwtZ2VudXNfT1RVX3RhYmxlWyxjKDcwOjcyKV0KZGF0JG90dSA8LSBhcy5mYWN0b3Iocm93bmFtZXMoZGF0KSkKZGF0JG90dSA8LSByZW9yZGVyKGRhdCRvdHUsIC1kYXQkcHJldiApCmRhdCRQaHlsdW0gPC0gYXMuZmFjdG9yKGRhdGEuZnJhbWUodGF4X3RhYmxlKGJiMTZTX2JhY19yYXJlZnlfdGF4X2dlbnVzKSkkUGh5bHVtKQpkYXQkbnVtYmVyIDwtIDE6bnJvdyhkYXQpCgpnZ3Bsb3QoZGF0LCBhZXMoeCA9IG90dSwgeT1wcmV2LCBmaWxsID0gUGh5bHVtKSkgKwogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9Y29sX3ZlY3RvcikgKyB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MueD1lbGVtZW50X2JsYW5rKCkpICsgeWxhYigiUHJldmFsYW5jZSIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQojZ2dzYXZlKCIuLi8uLi9Xcml0aW5nL0ZpbmFsX0ZpZ3MvY29yZV9wcmV2X293bGVnZW5kLmVwcyIpCgpnZ3Bsb3QoZGF0LCBhZXMoeCA9IG90dSwgeT1hYnVuZCwgIGZpbGwgPSBQaHlsdW0pKSArCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jb2xfdmVjdG9yKSArIHRoZW1lX2NsYXNzaWMoKSAgKyBzY2FsZV95X3JldmVyc2UoKSArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA0ICwgYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKI2dnc2F2ZSgiLi4vLi4vV3JpdGluZy9GaW5hbF9GaWdzL2NvcmVfYWJ1bmQuZXBzIikKCmdncGxvdChkYXQsIGFlcyh4ID0gb3R1LCB5PWFidW5kLCAgZmlsbCA9IFBoeWx1bSkpICsKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWNvbF92ZWN0b3IpICsgdGhlbWVfY2xhc3NpYygpICArIHNjYWxlX3lfcmV2ZXJzZSgpICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDQgLCBhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKyB5bGFiKCJQcm9wb3J0aW9uYWwgQWJ1bmRhbmNlIikgKyB4bGFiKCJPVFUgSUQiKQojZ2dzYXZlKCIuLi8uLi9Xcml0aW5nL0ZpbmFsX0ZpZ3MvY29yZV9hYnVuZF93b2xlZ2VuZC5lcHMiKQoKCiNjb2xvciBieSBjb3JlIGluY2x1c2lvbgoKZ2dwbG90KGRhdCwgYWVzKHggPSBvdHUsIHk9cHJldiwgZmlsbCA9IENvcmUpKSArCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjODhDQ0VFIiwgIiM5OTk5MzMiKSkgKyAKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MueD1lbGVtZW50X2JsYW5rKCkpICsgeWxhYigiUHJldmFsYW5jZSIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSAgKyB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSwgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNikpCmdnc2F2ZSgiLi4vLi4vV3JpdGluZy9GaW5hbF9GaWdzL2NvcmVfcHJldl9vd2xlZ2VuZF9Db3JlLmVwcyIpCgpnZ3Bsb3QoZGF0LCBhZXMoeCA9IG90dSwgeT1hYnVuZCwgIGZpbGwgPSBDb3JlKSkgKwogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzg4Q0NFRSIsICIjOTk5OTMzIikpICsgCiAgdGhlbWVfY2xhc3NpYygpICArIHNjYWxlX3lfcmV2ZXJzZSgpICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDQgLCBhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIGZhY2UgPSAiYm9sZCIpKSsgdGhlbWUoIGF4aXMudGV4dC54PWVsZW1lbnRfYmxhbmsoKSwgYXhpcy50aWNrcy54PWVsZW1lbnRfYmxhbmsoKSkgICsgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZT0xMiksIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTYpKQpnZ3NhdmUoIi4uLy4uL1dyaXRpbmcvRmluYWxfRmlncy9jb3JlX2FidW5kX0NvcmUuZXBzIikKCmdncGxvdChkYXQsIGFlcyh4ID0gb3R1LCB5PWFidW5kLCAgZmlsbCA9IENvcmUpKSArCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzg4Q0NFRSIsICIjOTk5OTMzIikpICsKICB0aGVtZV9jbGFzc2ljKCkgICsgc2NhbGVfeV9yZXZlcnNlKCkgKyMgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDQgLCBhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArIAp0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsgeWxhYigiUHJvcG9ydGlvbmFsIEFidW5kYW5jZSIpICsgeGxhYigiT1RVIikgKyB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X2JsYW5rKCksIGF4aXMudGlja3MueD1lbGVtZW50X2JsYW5rKCkpICsgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZT0xMiksIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTYpKQpnZ3NhdmUoIi4uLy4uL1dyaXRpbmcvRmluYWxfRmlncy9jb3JlX2FidW5kX3dvbGVnZW5kX0NvcmUuZXBzIikKCmBgYAoKCgoKCgoKIyMjIyBBY2lkb3BoaWxpYyBiYWN0ZXJpYSAKYW5hbHlzaXMgb2YgbGFjdGljIGFjaWQgYmFjdGVyaWEgYW5kIGFjZXRpYyBhY2lkIGJhY3RlcmlhIGF0IHRpbWUgcG9udCAyIChmb2xsb3dpbmcgYXBwbGljYXRpb24pCmBgYHtyfQpiYjE2U19iYWNfTUxfQjwtc3Vic2V0X3NhbXBsZXMoYmIxNlNfYmFjX01MLCBUaW1lcG9pbnQgPT0gIkIiKQojQUNFVE8KIzM2IHRheGEKYWNldG9iYWN0ZXIgPC0gc3Vic2V0X3RheGEoYmIxNlNfYmFjX01MX0IsIEZhbWlseSA9PSJBY2V0b2JhY3RlcmFjZWFlIikKYWNldG9iYWN0ZXJfZ2xvbWVkPC0gdGF4X2dsb20oYWNldG9iYWN0ZXIsIHRheHJhbmsgPSAiRmFtaWx5IikKCiNhbm92YSBmb3IgYWxsIHRheGEgY29tYmluZWQKZGF0PC1kYXRhLmZyYW1lKG90dV90YWJsZShhY2V0b2JhY3Rlcl9nbG9tZWQpKQpzYW1wX2Q8LWRhdGEuZnJhbWUoc2FtcGxlX2RhdGEoYWNldG9iYWN0ZXJfZ2xvbWVkKSkKbWVyZ2VkX2RhdDwtY2JpbmQoZGF0LCBzYW1wX2QpCiNjaGVjayB0byBtYWtlIHN1cmUgbWQgYW5kIG90dSB0YWJsZSBhcmUgaW4gc2FtZSBvcmRlci4gQWxsIHNob3VsZCBiZSB0cnVlLiAKdGFibGUobWVyZ2VkX2RhdCRYID09IHJvd25hbWVzKG1lcmdlZF9kYXQpKQojI21vZDwtYW92KE9UVV80MCB+IFRyZWF0bWVudCwgZGF0YSA9IG1lcmdlZF9kYXQpCiNzdW1tYXJ5KG1vZCkKI3Bsb3QocmVzaWR1YWxzKG1vZCkpCiNib3hwbG90KG1lcmdlZF9kYXQkT1RVXzQwIH4gbWVyZ2VkX2RhdCRUcmVhdG1lbnQpCgojYmFydXRhIGZvciBpbmRpdmlkdWFsIHRheGEKYWNldG9fZGYgPC0gY2JpbmQoZGF0YS5mcmFtZShvdHVfdGFibGUoYWNldG9iYWN0ZXIpKSwgZGF0YS5mcmFtZShzYW1wbGVfZGF0YShhY2V0b2JhY3RlcikpKQp0YWJsZShhY2V0b19kZiRYID09IHJvd25hbWVzKGFjZXRvX2RmKSkKYm94cGxvdChhY2V0b19kZiRPVFVfODIgfiBhY2V0b19kZiRUcmVhdG1lbnQpClZpZXcodGF4X3RhYmxlKGFjZXRvYmFjdGVyKSkKI290dSA4MiBJRCdlZCBieSBiYXJ1dGEuIE1vcmUgYWJ1bmRhbnQgaW4gT1JHLiBUYXhvbm9teSBmb3IgdGhpcyB0YXhhICJBY2V0b2JhY3RlcmFjZWFlLCBCb21iZWxsYSIKCmZvcihpIGluIDE6bGVuZ3RoKG5hbWVzKGRhdGEuZnJhbWUob3R1X3RhYmxlKGFjZXRvYmFjdGVyKSkpKSl7CiAgYm94cGxvdCh1bmxpc3QoYWNldG9fZGZbaV0pIH4gYWNldG9fZGYkVHJlYXRtZW50KQp9CgojdmVyeSB6ZXJvIGluZmxhdGVkIHNvIHdlIHdpbGwgbm90IHVzZSBhbm92YS4gCiNmb3IoaSBpbiAxOmxlbmd0aChuYW1lcyhkYXRhLmZyYW1lKG90dV90YWJsZShhY2V0b2JhY3RlcikpKSkpewojICBtb2Q8LWFvdih1bmxpc3QoYWNldG9fZGZbaV0pIH4gYWNldG9fZGYkVHJlYXRtZW50KQojICBzdW1tYXJ5KG1vZCkKIyAgcHJpbnQoc3VtbWFyeShtb2QpKQojICBwcmludChuYW1lcyhhY2V0b19kZltpXSkpCiN9Cgpmb3IoaSBpbiAxOmxlbmd0aChuYW1lcyhkYXRhLmZyYW1lKG90dV90YWJsZShhY2V0b2JhY3RlcikpKSkpewogIG1vZDwta3J1c2thbC50ZXN0KHVubGlzdChhY2V0b19kZltpXSkgfiBhY2V0b19kZiRUcmVhdG1lbnQpCiAgcHJpbnQobW9kKQogIHByaW50KG5hbWVzKGFjZXRvX2RmW2ldKSkKfQoKI09UVSA4MiBJRCdlZCBhcyBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBhbW9uZyBncm91cHMKcGFpcndpc2Uud2lsY294LnRlc3QoYWNldG9fZGYkT1RVXzgyLCBhY2V0b19kZiRUcmVhdG1lbnQpCmJveHBsb3QoYWNldG9fZGYkT1RVXzgyfiBhY2V0b19kZiRUcmVhdG1lbnQpCmdncGxvdChhY2V0b19kZiwgYWVzKHggPSBUcmVhdG1lbnQsIHkgPSBPVFVfODIsIGNvbG9yID0gVHJlYXRtZW50KSkgKyBnZW9tX2JveHBsb3QoKSAgKyB0aGVtZV9jbGFzc2ljKCkgICsgdGhlbWUoYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksIGF4aXMudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MTQpKQpnZ3NhdmUoIi9Vc2Vycy9nb3Jkb25jdXN0ZXIvRGVza3RvcC9HaXRfUHJvamVjdHMvQmVlQnJlYWQvV3JpdGluZy9GaW5hbF9GaWdzL09UVV84Ml9NTC5lcHMiKQoKI25vIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIGFjcm9zcyB0cmVhdG1lbnQgdHlwZXMKYGBgCgoKCmBgYHtyfQojI0xBQ1RPCgojNzUgdGF4YQpsYWN0b2JhYyA8LSBzdWJzZXRfdGF4YShiYjE2U19iYWNfTUxfQiwgT3JkZXIgPT0iTGFjdG9iYWNpbGxhbGVzIikKbGFjdG9iYWNfZ2xvbWVkIDwtIHRheF9nbG9tKGxhY3RvYmFjLCB0YXhyYW5rID0gIk9yZGVyIikKCmRhdDwtZGF0YS5mcmFtZShvdHVfdGFibGUobGFjdG9iYWNfZ2xvbWVkKSkKc2FtcF9kPC1kYXRhLmZyYW1lKHNhbXBsZV9kYXRhKGxhY3RvYmFjX2dsb21lZCkpCm1lcmdlZF9kYXQ8LWNiaW5kKGRhdCwgc2FtcF9kKQojY2hlY2sgdG8gbWFrZSBzdXJlIG1kIGFuZCBvdHUgdGFibGUgYXJlIGluIHNhbWUgb3JkZXIuIEFsbCBzaG91bGQgYmUgdHJ1ZS4gCnRhYmxlKG1lcmdlZF9kYXQkWCA9PSByb3duYW1lcyhtZXJnZWRfZGF0KSkKCmxhY3RvX2RmIDwtIGNiaW5kKGRhdGEuZnJhbWUob3R1X3RhYmxlKGxhY3RvYmFjKSksIGRhdGEuZnJhbWUoc2FtcGxlX2RhdGEobGFjdG9iYWMpKSkKdGFibGUobGFjdG9fZGYkWCA9PSByb3duYW1lcyhsYWN0b19kZikpCmJveHBsb3QobGFjdG9fZGYkT1RVXzUzMCB+IGxhY3RvX2RmJFRyZWF0bWVudCkKVmlldyh0YXhfdGFibGUobGFjdG9iYWMpKQoKCgpmb3IoaSBpbiAxOmxlbmd0aChuYW1lcyhkYXRhLmZyYW1lKG90dV90YWJsZShsYWN0b2JhYykpKSkpewogIGJveHBsb3QodW5saXN0KGxhY3RvX2RmW2ldKSB+IGxhY3RvX2RmJFRyZWF0bWVudCkKfQoKZm9yKGkgaW4gMTpsZW5ndGgobmFtZXMoZGF0YS5mcmFtZShvdHVfdGFibGUobGFjdG9iYWMpKSkpKXsKICAgbW9kPC1rcnVza2FsLnRlc3QodW5saXN0KGxhY3RvX2RmW2ldKSB+IGxhY3RvX2RmJFRyZWF0bWVudCkKICBwcmludChtb2QpCiAgcHJpbnQobmFtZXMobGFjdG9fZGZbaV0pKQp9CmBgYAoKCgoKaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNjE3OTY0ODQvc3RhY2tlZC1iYXItY2hhcnQtd2l0aC1jb3VudC1hYm92ZS1hbmQtYmVsb3cteC1heGlz